如何调整一行中的第n个数字?

如何调整一行中的第n个数字?

文件内容:

RANDOM TEXT    num1=400    num2=15    RANDOM TEXT
RANDOM TEXT    num1=300    num2=10    RANDOM TEXT
RANDOM TEXT    num1=200    num2=5    RANDOM TEXT

我想为每行的每个 num2 减去 5,如下所示:

RANDOM TEXT    num1=400    num2=10    RANDOM TEXT
RANDOM TEXT    num1=300    num2=5    RANDOM TEXT
RANDOM TEXT    num1=200    num2=0    RANDOM TEXT

纯 bash 是首选,但如果另一个 GNU 工具做得更好也没什么大不了的。

答案1

使用awk

awk '{ for (i=1;i<=NF;i++) { if ($i ~ /num2=/) {sub(/num2=/, "", $i); $i="num2="$i-5; print} } }' file

这将循环遍历每行的每一列,查找包含 的列num2=。当它找到该列时,它将:

  1. 消除num2=-sub(/num2=/, "", $i)
  2. 将该列重新定义为num2={oldnum-5}-$i="num2="$i-5
  3. 打印该行 -print

答案2

珀尔:

perl -pe 's/(?<=num2=)(\d+)/$1 - 5/e' file

要将内容存储回文件中:

perl -i -pe ...

答案3

[只是因为我试图更熟悉磨坊主- 它需要一些跳跃才能获得异构输出]

$ mlr --fs ' ' --repifs --ocsvlite --headerless-csv-output put '
    $num1 = "num1=".$num1; $num2 = "num2=".($num2-5)
' file
RANDOM TEXT num1=400 num2=10 RANDOM TEXT
RANDOM TEXT num1=300 num2=5 RANDOM TEXT
RANDOM TEXT num1=200 num2=0 RANDOM TEXT

如果输入实际上是 TSV,其中某些列可能包含空格,则

$ mlr --fs '\t' --ocsvlite --headerless-csv-output put '
    $num1 = "num1=".$num1; $num2 = "num2=".($num2-5)
' file
RANDOM TEXT num1=400    num2=10 RANDOM TEXT
RANDOM TEXT num1=300    num2=5  RANDOM TEXT
RANDOM TEXT num1=200    num2=0  RANDOM TEXT

答案4

使用 Vim:

vim +'g/^/exe "norm! 3Wf=5\<C-A>"' +wq file

首先+争论在每行上运行一系列正常模式操作以将数字增加 5 倍。它使用一个:global命令在每一行上运行它。只需使用:normal与一个范围 %norm如果我们不使用的话会更简单CTRLA增加数字,但为了(轻松)将此控制字符传递到 Vim,我们将命令构建为要运行的字符串:execute,因此我们需要:global.

第二个+参数很简单保存文件

如果随机文本的格式不太规则(或者您只是更喜欢正则表达式),您可以使用:substitute命令:

vim +'%s/num2=\zs\d\+/\=submatch(0) + 5' +wq file

这使用命令将的 部分:substitute替换为Nnum2=N现有价值加五。

相关内容