我使用这段代码在每 20 行之后开始一个新列,并且每列都由制表符分隔。我从这篇文章中获取了代码,然后对其进行了一些调整:如何在每第 n 行后开始一个新列?
awk '{a[NR%20] = a[NR%20] (NR<=20 ? "" : "\t") $0} END {for (i = 1; i <= 20; i++) print a[i%20]}'
它完全按照我想要的方式做。但是,我不太明白它是如何工作的。有人可以向我解释一下吗?我知道它将$0
读入文件的整个记录(行),并且评估问号之前的条件,如果为 true,则执行第一个语句,如果为 false,则执行第二个语句。因此,在这种情况下,如果NR<=20
then 则不会打印任何内容,因为我们位于第一列,但如果NR>20
then 则打印一个选项卡以开始新列。我还知道 for 循环打印出数组的元素,从a[1%20]
is开始a[1]
,依次类推,到a[19%20]
is a[19]
,最后a[20%20]
是 is a[0]
。但它有什么a[NR%20] = a[NR%20]
作用呢?为什么它设置为等于自身?我发现当我省略 时a[NR%20] = a[NR%20]
,会打印出 20 个空行。
答案1
在 中awk
,由空格分隔的表达式连接在一起。 POSIX awk 手册中描述了这种串联表达式表(该页面上的格式不是很清楚,通过 更容易阅读man 1p awk
)。与其当前值 + / + 当前记录a[NR%20]
连接在一起。对于前二十条记录,数组值和三元表达式都将为空字符串。括号可能会更清楚:""
"\t"
?:
a[NR%n] = (a[NR%n] (NR<=n ? "" : "\t") $0)
答案2
(NR<=20 ? "" : "\t")
正在修改第二个a[20%20]
,因此它不会设置为等于自身,但如果 NR > 20,则会附加一个表格。
然后 END 脚本(右大括号内的部分)打印结果。