[英]awk: mysterious double line print
I have a $FILE 我有一个$ FILE
1 textline1
1 textline2
1 textline3
1 textline4
I want to search for textline3 and make sum: 1stcolumn+1 我想搜索textline3并进行求和:1stcolumn + 1
Linenumber is: Linenumber是:
lnr=$(grep -n textline3 $FILE | cut -d : -f1)
But when i use awk: 但是当我使用awk时:
awk -v l="$lnr" 'FNR==l{ sub($1,$1 + 1); print }1' $FILE
I get the erroneous (3rd line is double printed) 我得到了错误(第3行是双重打印)
1 textline1
1 textline2
2 textline3
2 textline3
1 textline4
Reason for double printing is , you are printing inside {} and using 1 as well. 双重打印的原因是,您在{}内打印并使用1。 1 means true and awk's default behaviour is to print.
1表示true,awk的默认行为是打印。
awk -v l="$lnr" 'FNR==l{ sub($1,$1 + 1)}1' $FILE
You can avoid the usage of grep
and let awk
do the magic. 你可以避免使用
grep
并让awk
做出魔法。
awk '/textline3/{sub($1,$1 + 1)}1' file
1 textline1
1 textline2
2 textline3
1 textline4
In general, you can do a awk '/<pattern>/ { <action> }' file
for manipulation. 通常,您可以执行
awk '/<pattern>/ { <action> }' file
进行操作。
If you just want to increment the first field on the N th line, just say so: 如果你只是想增加第 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
Note the 1
here is triggering awk
's default action, consisting in printing the current line. 注意这里的
1
是触发awk
的默认动作,包括打印当前行。 For every line it will print the initial value but for the line number line
it will print the 1 st value with its value +1. 对于每一行,将打印的初始值而对于行号
line
将打印其值+1的1 日的价值。
And that's why you see that line twice in your code: because in the action triggered by FNR==line
you are already calling print
. 这就是为什么你在代码中看到两行的原因:因为在
FNR==line
触发的动作中你已经调用了print
。
Theres a few problems with your script: 你的脚本有一些问题:
print
inside the action block and then the 1
at the end of the script is a constant true condition which will cause awk to execute it's default action of printing the record again. print
,然后脚本末尾的1
是一个常量的真实条件,这将导致awk执行它再次打印记录的默认操作。 l
(el) as a variable name, it looks far too much like the number 1
(one) and so makes your code harder to read. l
(el)作为变量名称,它看起来太像数字1
(一),因此使您的代码更难阅读。 $1
, just do $1++
(assuming textline3
doesn't contain chains of white space that must not be concatenated into one blank char). $1
,只需要$1++
(假设textline3
不包含不能连接成一个空白字符的空格链)。 $1
) as either the search regexp or replacement string fields of any *sub() command as that will fail cryptically given various regexp or backreference metacharacters in the input. $1
)作为任何* sub()命令的搜索regexp或替换字符串字段,因为在输入中给定各种正则表达式或反向引用元字符,这将会加密失败。 So your script should be just: 所以你的脚本应该只是:
$ awk '/textline3/{$1++}1' file
1 textline1
1 textline2
2 textline3
1 textline4
Solution using perl
使用
perl
解决方案
$ perl -pe 's/^(\d+)(?=\s*textline3)/$1+1/e' $FILE
1 textline1
1 textline2
2 textline3
1 textline4
or 要么
perl -pe 's/^(\d+)/$1+1/e if /textline3/' $FILE
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.