繁体   English   中英

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

[英]In a shell (bash) How can I execute more than one command in a pipeline?

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

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

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

提前致谢。

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

尝试这个:

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

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

编辑:纠正了基于进一步测试发生的事情的描述。

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

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

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

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

如果awk命令可能在输入的末尾打印一些空行,则$()构造将剥离,这与额外的a复杂化。 您可以轻松选择首先出现的sortwc


这是一种适用于任何POSIX shell(ash,bash,ksh,zsh,...)的方法,但仅适用于具有/dev/fd (包括合理的Linux,* BSD和Solaris)的系统。 就像Walter使用bash,ksh93和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。

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM