AWK中管道语法的混淆

时间:2012-10-22 02:55:34

标签: shell awk pipe

示例代码是这样的,它会显示第一列出现次数的统计信息并对结果进行排序。

    { dist[$1]+=1; }
END { for (i in dist) {
        print i,dist[i] | "sort"
      }
    }

在我看来,这个过程是这样的:

(工作流程A)

1)打印dist中的所有元素,将它们全部保存到缓冲区

2)获取缓冲区中的所有元素,并将它们传递给sort函数

但在上面的示例中,过程如下所示:

(工作流程B)

1)在dist中打印一个元素,然后将其传递给sort函数

2)处理dist中的下一个元素,直到dist中没有新元素

我想知道为什么我不应该像这样放置sort

    { dist[$1]+=1; }
END { for (i in dist) {
        print i,dist[i] 
      } 
      | "sort"
    }

任何人都知道原因吗?如果我想像pipe那样开展工作,如何编写WORKFLOW B

谢谢!

2 个答案:

答案 0 :(得分:3)

你不能这样做的第二种方式是因为| "command"是awk的print命令语法的一部分,它不能用于任意语句或语句组。同样适用于> filename

它的工作方式是,第一次遇到重定向到文件或管道时,它会打开该文件/管道,并保持该描述符处于打开状态。然后,每次重定向到同一文件/管道时,它都会将输出发送到相应的描述符。

答案 1 :(得分:0)

请参阅@ barmar对“为什么不”的回答,以及如何获得该功能(在循环结束时调用排序)以解决问题的第二部分:

    { dist[$1]+=1; }
END { for (i in dist) {
        out = out i OFS dist[i] ORS 
      } 
      printf "%s",out | "sort"
    }