5

我有一个简单的 awk one 划线器,当匹配给定模式时,它会将下一行折叠到当前行上。这里是:

awk '/two/ { printf $1; next; } 1' test.txt 

使用以下输入:

one
two
three
four
five
six

one
two
three 
four

你得到:

one
twothree
four
five
six

one
twothree 
four

请注意,“三”与“二”折叠在一起,这是我想要发生的。我找到了这个解决方案(不记得在哪里),并且奇怪的是尾随的“1”似乎是导致预期效果的缺失部分。如果你把它拿出来,你会得到:

awk '/two/ { printf $1; next; }' test.txt 
twotwo

作为结果。所以我的问题是,尾随的“1”是做什么的,它记录在哪里?

谢谢!

4

3 回答 3

6

对于awk, 1 表示为真,当表达式为真时,awk默认打印当前行。

例子 :

  • awk '1' /etc/passwd将打印整个文件
  • awk '0' /etc/passwd不会打印整个文件

如果你擅长算术(或者你有想象力或编程技能),你可以用这种行为做很多技巧。

于 2012-10-23T20:28:34.877 回答
3

“整个 Awk 单行代码末尾的 '1' 打印出修改后的行(它只是“print”的语法糖(它本身就是“print $0”的语法糖))”。

--纸垫

于 2012-10-23T20:28:38.937 回答
1

你得到了你的具体问题的答案,但你发布的脚本是不安全的。printf 的第一个参数是格式字符串,而不是数据。您有时可以使用它来打印数据,但只有在脚本中硬编码时才能使用它,而不是从输入中读取数据时。看看如果您的输入恰好包含 printf 格式字符串会发生什么:

$ cat file
one
two%s
three
four

$ awk '/two/ { printf $1; next; } 1' file
one
awk: cmd. line:1: (FILENAME=file2 FNR=2) fatal: not enough arguments to satisfy format string
        `two%s'
            ^ ran out for this one

编写脚本的正确方法是:

$ awk '/two/ { printf "%s",$1; next; } 1' file
one
two%sthree
four
于 2012-10-23T20:51:42.820 回答