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

时间:2010-08-03 15:29:11

标签: bash shell awk pipeline

我正在尝试在Bash shell中同时通过多个命令输出awk命令的输出,据我所知,我想出了这个:

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

我希望awk命令的结果都被计算和排序,我该如何实现? 即使使用&&命令它不起作用,它执行第一个命令,然后退出。 我想这是我对bash失败的了解。

提前致谢。

5 个答案:

答案 0 :(得分:5)

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

试试这个:

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

这将输出stderr上的行数和stdout上的已排序输出。如果你需要stdout上的行数,你可以不用>&2,但它会被传递给排序调用,并且(很可能)排序到输出的顶部。

编辑:根据进一步测试纠正了对所发生情况的描述。

答案 1 :(得分:4)

在那种情况下,你在awk中计数,为什么需要管道?不要让它变得更复杂

awk '$13 ~ /type/ {print $15;c++}END{print c} ' filename.txt | sort -u

答案 2 :(得分:1)

如果输出中的大小不是太大而不适合内存而且由于性能原因你不需要wcsort命令并行工作,这里有一个相对简单的解决方案:

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

额外a的复杂性是因为awk命令可能在输入的末尾打印一些空行,$()构造将剥离。您可以轻松选择首先显示sortwc中的哪一个。


这是一种适用于任何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类似,wc的输出和sort的输出可能会混合在一起。

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

如果你们都需要处理不适合内存的中间输出不希望两个命令的输出混合在一起,我认为这并不容易在POSIX shell中的方式,虽然它应该适用于ksh或zsh coprocesses。

答案 3 :(得分:0)

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

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

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

答案 4 :(得分:0)

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