如何在具有相同数字的每一行中增加一个数字

如何在具有相同数字的每一行中增加一个数字

示例文件有

test test test test test
TEST: 15000
abcabc TEST: 15000 testtest test
TEST: 15000
test test  test 14000 test test test
TEST: 15000
TEST: 15000

当它看到 15000 时,无论文本是什么,它都必须变得如此,只需在每行上增加 1

test test test test test
TEST: 15001
abcabc TEST: 15002 testtest test
TEST: 15003
test test  test 14000 test test test
TEST: 15004
TEST: 15005

答案1

perl

$ cat file
TEST: 15000
TEST: 15000
TEST: 15000 15000 -15000 015007 15000e-1 1.15000
OTHER: 1000 1000 1000
AND: 1000 1000 0x14999 14999
$ perl -pe 's{\d+}{$& + ++$c{$&}}ge' file
TEST: 15001
TEST: 15002
TEST: 15003 15004 -15005 15008 15006e-2 3.15007
OTHER: 1001 1002 1003
AND: 1004 1005 1x15000 15001
$ perl -pe 's{\d+}{$& + $c{$&}++}ge' file
TEST: 15000
TEST: 15001
TEST: 15002 15003 -15004 15007 15005e-1 2.15006
OTHER: 1000 1001 1002
AND: 1003 1004 0x14999 15000

它仅处理十进制数字序列。因此请注意,如果输入中除了正十进制整数之外的任何内容,它可能不会给您预期的结果,如上面所示。

请注意,上面的 015000 仍然被视为十进制(不是八进制),但不被视为与 15000 相同,因为比较是词法的,而不是数字的。替换$c{$&}$c{0+$&}以进行数值比较(通过将用作关联数组键的数字规范化,%c该数组会记住每个唯一数字的增量)。

如果目的是确保所有数字都不同,请注意它也不会这样做。查看第一次出现的 15000 如何转换为与上面第二次出现的 14999 相同的数字。

另请注意,大于 2 64 - 1 (18446744073709551615) 的数字将以科学记数法表示(并失去精度)。 Add-Mbignum可以处理任意大的数字,但您还需要通过在运算中插入 1 来强制转换为 bignum:

$ perl -pe 's{\d+}{$& + ++$c{$&}}ge' <<< 99999999999999999999
1e+20
$ perl -Mbignum -pe 's{\d+}{0 + $& + ++$c{$&}}ge' <<< 99999999999999999999
100000000000000000000

答案2

$ awk '{$2 += ++i}1' test.txt 
TEST: 15001
TEST: 15002
TEST: 15003

递增i并添加到$2

顺便说一句,变量i在第一次递增时不存在,因此它是用初始值创建的0,然后递增到1 它被添加到字段 2。如果它被写成而i++不是++i那么它会增加初始值 (0) 添加到 $2。

如果您只想在 $2 = 15000 时增加行数,则:

awk '$2 == 15000 {$2 += ++i}1' test.txt 

或者,使用 perl,使用 perl 的/e正则表达式修饰符将 s/// 运算符的 RHS 计算为 perl 表达式:

TEST: 15000.5(我在示例输入的末尾添加了额外的一行)

$ perl -p -e 's/\d+/$& == 15000 ? $& + ++$i : $&/eg' input.txt 
test test test test test
TEST: 15001
abcabc TEST: 15002 testtest test
TEST: 15003
test test  test 14000 test test test
TEST: 15004
TEST: 15005
TEST: 15006.5

英文:对于一行中找到的任何数字,如果该数字等于 15000,则将其替换为自身加上预递增变量$i,否则将其替换为自身。

与 awk 中一样,$i如果在不存在时使用,则使用初始值 0(如果用作字符串则为空字符串)创建。顺便说一句,当变量名称中有拼写错误(或者在变量的作用域之外使用变量时),这是运行时错误的一个非常常见的来源,因此 Perl 有一个use strict编译指示要求所有变量和其他标识符要么完全是-指定或在使用之前声明。使用未声明的变量将导致编译时错误,因此可以在运行错误程序造成任何损害之前发现并修复该错误。由于这只是一个简单的单行代码,并且仅使用一个变量(并且仅使用一次),因此我strict在这里不使用。

或者,如果有可能的话,15000.5输入中可能会有类似的数字,而您希望它们也增加++$i

$ perl -p -e 's/(\d+)([^.])/($1 == 15000 ? $1 + ++$i : $1) . $2/eg' input.txt
test test test test test
TEST: 15001
abcabc TEST: 15002 testtest test
TEST: 15003
test test  test 14000 test test test
TEST: 15004
TEST: 15005
TEST: 15000.5

此版本捕获两种模式,一个数字(如 $1)和数字后面的任何字符(如 $2),只要该字符不是小数点 ( .)。您可能应该在使用逗号或其他内容的语言环境中更改此设置。成功匹配时,替换的计算方式与第一个 Perl 版本完全相同,但 $2 是用 Perl 的字符串连接运算符 ( .) 附加到它的后面。

相关内容