如何理解命令 awk '{for(x=1;$x;++x)print $x}'?

Zen*_*Zen 5 awk

我知道这个命令

awk '{for(x=1;$x;++x)print $x}' 
Run Code Online (Sandbox Code Playgroud)

将打印出一行中的所有列。

这不会++x 更改x为 2,从而$2先打印吗?正如我所理解的:https : //stackoverflow.com/questions/1812990/incrementing-in-c-when-to-use-x-or-x

$xin 做for(x=1;$x;++x)什么?

ter*_*don 14

不是。这for(i=0;i<10;i++)是一种经典的编程结构(请参阅传统 for 循环),存在于许多语言中。它可以分解为:

start-expression; end-condition; end-of-iteration-expression
Run Code Online (Sandbox Code Playgroud)

换句话说,我上面写的意思是“将 i 初始化为 0,当 i 小于 10 时,做一些事情并且 然后将i 增加 1。是的,语法令人困惑,但这就是它的方式。end-of-iteration-expression(++x在这种情况下) 在每个循环结束时执行一次。相当于写:

while(i<10){print i; ++i}
Run Code Online (Sandbox Code Playgroud)

至于$x,我相信只需检查该数字的字段是否存在并且其内容不会评估为 false(如下面 Mathias 的回答中所述)。$N如果字段编号 N 存在且不是 的类型,则将返回 true false。例如:

$ echo "a b c d" | awk '($4){print "yes"}'
yes
$ echo "a b c d" | awk '($14){print "yes"}' ## prints nothing, no $14
$ echo "a b c 0" | awk '($4){print "yes"}' ## prints nothing, $4 is 0
Run Code Online (Sandbox Code Playgroud)

正如您在上面看到的,第一个命令会打印,yes因为有一个$4. 由于没有$14,第二个不打印任何内容。所以,回到你原来的例子:

awk '{for(x=1;$x;x++)print $x}' 
          ___ __ ___
           |   |  |
           |   |  |-----> increment x by 1 at the end of each loop.
           |   |--------> run the loop as long as there is a field number x
           |------------> initialize x to 1
Run Code Online (Sandbox Code Playgroud)


Mat*_*ner 6

由于 terdon 提供了一个全面的答案,我只想补充一点,如果任何列的计算结果为 false,则 for 语句将结束循环,如您在此示例中所见:

$ echo 1 2 3 4 5 0 6|awk '{for(x=1;$x;++x)print $x}' 
1
2
3
4
5
Run Code Online (Sandbox Code Playgroud)

  • 更正确的 awk 程序是 `{for(x=1;$x"";++x)print $x}`。这是有效的,因为它将测试表达式的类型固定为 *string*,而不是 *numeric string*,并且仅当字符串为空时,字符串才为 false。使用默认的“FS”,空字段只能出现在字段的末尾。 (2认同)