代码之家  ›  专栏  ›  技术社区  ›  OverLex

在shell(bash)中,如何在管道中执行多个命令?

  •  4
  • OverLex  · 技术社区  · 15 年前

    我正在尝试在Bash shell中同时通过多个命令对awk命令的输出进行管道传输,根据我的知识,我得出以下结论:

    awk '$13 ~ /type/ {print $15}' filename.txt | (wc -l || sort -u)
    

    我想失败的是我对bash的了解。

    提前谢谢。

    5 回复  |  直到 15 年前
        1
  •  5
  •   Walter Mundt    15 年前

    如果要在一行中向两个不同的命令发送输出,则需要进行进程替换。

    试试这个:

    awk '$13 ~ /type/ {print $15}' filename.txt | tee >(wc -l >&2) | sort -u
    

    这将输出stderr上的行计数和stdout上的排序输出。如果你需要在stdout上计算行数,你可以这样做 >&2 ,但随后它将被传递到sort调用并(很可能)排序到输出的顶部。

        2
  •  4
  •   ghostdog74    15 年前

    那样的话,你用awk计算,为什么需要管道?别把事情弄复杂了

    awk '$13 ~ /type/ {print $15;c++}END{print c} ' filename.txt | sort -u
    
        3
  •  1
  •   Community Mohan Dere    8 年前

    如果输出的大小不是太大,无法放入内存,并且您不需要 wc sort 由于性能原因,命令要并行工作,这里有一个相对简单的解决方案:

    output=$(awk '$13 ~ /type/ {print $15}' filename.txt; echo a)
    printf "%s" "${output%a}" | sort -u
    printf "%s" "${output%a}" | wc -l
    

    那个额外的并发症 a 以防 awk 命令可能会在输入的末尾打印一些空行,而 $() 建筑会剥落。你可以很容易地选择 分类 厕所


    这里有一种方法可以与任何POSIX shell(ash、bash、ksh、zsh……)一起工作,但只能在具有 /dev/fd (包括相当新的Linux、*BSD和Solaris)。就像 Walter's similar construction using the simpler method available in bash, ksh93 and zsh ,输出 厕所 分类 可能混杂在一起。

    {
      awk '$13 ~ /type/ {print $15}' filename.txt |
      tee /dev/fd3 |
      wc -l
    } 3>&1 1>&3 | sort -u
    

    我不想让这两个命令的输出混合在一起,我认为在POSIX shell中没有一个简单的方法,尽管在ksh或zsh协进程中应该是可行的。

        4
  •  0
  •   Greg Reynolds    15 年前

    您希望将使用mkfifo创建的命名管道与tee结合使用。例如 http://www.softpanorama.org/Tools/tee.shtml

        5
  •  0
  •   riwalk    15 年前

    我认为更大的问题是:你期望的产出是什么?

    如果你想做两件事,那就做两件事:

    awk '$13 ~ /type/ {print $15}' filename.txt > tempfile
    wc -l < tempfile
    sort -u < tempfile
    rm tempfile