繁体   English   中英

awk:神秘的双线打印

[英]awk: mysterious double line print

我有一个$ FILE

1 textline1
1 textline2
1 textline3
1 textline4

我想搜索textline3并进行求和:1stcolumn + 1

Linenumber是:

lnr=$(grep -n textline3 $FILE | cut -d : -f1)

但是当我使用awk时:

awk -v l="$lnr" 'FNR==l{ sub($1,$1 + 1); print }1' $FILE

我得到了错误(第3行是双重打印)

1 textline1
1 textline2
2 textline3
2 textline3
1 textline4

双重打印的原因是,您在{}内打印并使用1。 1表示true,awk的默认行为是打印。

awk -v l="$lnr" 'FNR==l{ sub($1,$1 + 1)}1' $FILE

你可以避免使用grep并让awk做出魔法。

awk '/textline3/{sub($1,$1 + 1)}1' file
1 textline1
1 textline2
2 textline3
1 textline4

通常,您可以执行awk '/<pattern>/ { <action> }' file进行操作。

如果你只是想增加 n 线上的第一个字段,只是这么说:

$ awk -v line=3 'FNR==line {$1+=1}1' file  # line is more readable than l
1 textline1
1 textline2
2 textline3
1 textline4

注意这里的1是触发awk的默认动作,包括打印当前行。 对于每一行,将打印的初始值而对于行号line将打印其值+1的1 的价值。

这就是为什么你在代码中看到两行的原因:因为在FNR==line触发的动作中你已经调用了print

你的脚本有一些问题:

  1. 您要问的具体错误:您在操作块内部调用print ,然后脚本末尾的1是一个常量的真实条件,这将导致awk执行它再次打印记录的默认操作。
  2. 永远不要使用字母l (el)作为变量名称,它看起来太像数字1 (一),因此使您的代码更难阅读。
  3. 你不需要函数调用来改变$1 ,只需要$1++ (假设textline3不包含不能连接成一个空白字符的空格链)。
  4. 您不需要使用grep + wc来查找行,只需将其保存在awk中即可。
  5. 一般情况下,您应该避免使用输入数据(例如$1 )作为任何* sub()命令的搜索regexp或替换字符串字段,因为在输入中给定各种正则表达式或反向引用元字符,这将会加密失败。

所以你的脚本应该只是:

$ awk '/textline3/{$1++}1' file
1 textline1
1 textline2
2 textline3
1 textline4

使用perl解决方案

$ perl -pe 's/^(\d+)(?=\s*textline3)/$1+1/e' $FILE
1 textline1
1 textline2
2 textline3
1 textline4

要么

perl -pe 's/^(\d+)/$1+1/e if /textline3/' $FILE

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM