有没有perl行来增加文件中一行的数字?

carvr3hs  于 2022-11-15  发布在  Perl
关注(0)|答案(2)|浏览(170)

我有一个文件,其中有一行是这样的:

onspaces -a dataidx -p /dev/itest17/idx_dataidx20 -o 0 -s 2097150

我需要将该数字加1,这样输出将是:

onspaces -a dataidx -p /dev/itest17/idx_dataidx21 -o 0 -s 2097150

也可以有一行,例如:

onspaces -a dataidx -p /dev/itest17/foobar01 -o 0 -s 2097150

这将导致

onspaces -a dataidx -p /dev/itest17/foobar02 -o 0 -s 2097150

我试过了

`perl -i -pe 'if ($. == 1) 
{($n) = ($m) = /([09]+)$/;
++$m;s/$n/$m/g;
} else {s/$n(?= )/$m/;}' in_file`

这是我之前问的一个问题的解决方案,这个问题已经解决了,但是这个问题似乎有点不同。提前感谢!
注意:我使用的是Perl的旧版本,5.8.3。

pieyvz9o

pieyvz9o1#

类似于我之前提供给您的解决方案:

perl -i~ -pe 's/([0-9]+)(?= -o)/$x = $1; ++$x/e' file

例如,找到一个数字序列[0-9]+,后面跟着一个空格和-o (?= -o),用递增的数字替换数字。/e将替换解释为要运行的代码,使用++确保保留前导零。

guz6ccqo

guz6ccqo2#

这里唯一真正“移动的部分”是关于在行中找到数字所在的位置。

perl -pe's{\-p\s+/\S+[^0-9]\K([0-9]+)\b}{ $n = $1; ++$n }e' file

使用$n(而不仅仅是1+$1)的“操作”是为了确保前导零保持不变。†要在彻底测试后就地更改文件,如问题中所述,添加-i
这是一个假设,因为这个问题不是很精确(例如,路径没有空格)。它可以根据需求的细节进行调整,或者简化。
简要说明和替代方案
/e修饰符将替换端作为代码进行计算,这样我们就可以在那里进行计算,然后将代码返回的内容用作替换。\K很好地“丢弃”了到该点为止的所有匹配,因此替换不会触及以前的匹配。
但是,注解澄清了这是perlv5.8.3; \K在当时(20年前)还不存在,没有它,我们必须捕获要更改的数字之前的所有内容,然后将其放回原处

perl -pe's{(\-p\s+/\S+[^0-9])([0-9]+)\b}{ $n=$2; $1.(++$n) }e' file

最后,[^0-9](不是一个数字)在那里“停止”先前的\S+的贪婪,需要匹配一个路径,以便路径中的最后一个数字可以被完全匹配(\S+将只为最后的[0-9]+留下一个数字)。
†当一个数字被用于数值环境时,它可能会丢失前导零(通常是这样的)。然而,当它被用作字符串时,自动递增操作符不会丢失前导零,而在正则表达式的替换端,它会丢失前导零。
jhnc在注解中的一个技巧也使它保持紧凑

perl -pe's{(\-p\s+/\S+[^0-9])\K([0-9]+)\b}{ ++($_=$1) }e' file

或者,在perl-5.8.3-has-no-\K的情况下

perl -pe's{(\-p\s+/\S+[^0-9])([0-9]+)\b}{ $1.(++($_=$2)) }e' file

相关问题