锥子里面的管道是如何工作的(用保留表头排序)



以下命令输出文件的标头,并对标头后的记录进行排序。但它是如何工作的呢?有人能解释一下这个命令吗?

awk 'NR == 1; NR > 1 {print $0 | "sort -k3"}'

请您复习一下以下内容(仅供解释(。为了学习更多关于awk的概念,我建议阅读Stack overflow的漂亮的awk学习部分

awk '                    ##Starting awk program from here.
NR == 1;                 ##Checking if line is first line then print it.
##awk works on method of condition then action since here is NO ACTION mentioned so by default printing of current line will happen
NR > 1{                  ##If line is more than 1st line then do following.
print $0 | "sort -k3"   ##It will be keep printing lines into memory and before printing it will sort them with their 3rd field.
}'

理解awk命令:总体而言,awk程序是由(pattern){action}对构建的,这些对表示如果pattern返回非零值,则执行action。一个不一定,需要写两个。如果省略了pattern,则默认为1;如果省略action,则缺省为print $0

查看有问题的命令时:

awk 'NR == 1; NR > 1 {print $0 | "sort -k3"}'

我们注意到有两个动作模式对。第一个读取NR == 1,并声明如果我们正在处理第一条记录(模式(,则打印该记录(默认操作(。第二个有点棘手。模式是明确的,另一方面行动需要一些解释。

awk知道4个可以重定向输出的输出语句。其中一个读作expression | cmd。这本质上意味着awk将把输出写入一个流,该流通过管道作为命令cmd的输入。它将继续将输出写入该流,直到使用close(cmd)语句或简单地终止awk显式关闭该流。

在OP的情况下,操作读取{ print $0 | "sort -k3" },这意味着它将把所有记录$0打印到用作shell命令sort -k3输入的流中。只有当程序完成时,sort才会写入其输出。

重述:OP的命令将打印文件的第一行,并根据第三列对连续的行进行排序。

替代解决方案:

使用GNU awk,最好这样做:

awk '(FNR==1);{a[$3]=$0}
END{PROCINFO["sorted_in"]="@ind_str_asc"
for(i in a) print a[i]
}' file

使用纯外壳,最好做:

cat file | (read -r; printf "%sn" "$REPLY"; sort -k3)

相关问题:

  • 有没有一种方法可以忽略UNIX排序中的头行

|是print和printf支持的重定向之一,在本例中是指向命令sort -k3的管道。您也可以使用重定向来使用>:写入文件

awk 'NR == 1; NR > 1 {print $0 > "output.txt"}'

或使用>>:附加到文件

awk 'NR == 1; NR > 1 {print $0 >> "output.txt"}'

第一个将向文件output.txt写入除第一行以外的所有行,第二个将向output.txt追加除第一行之外的所有行。

最新更新