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

发布于 2024-09-13 01:37:18 字数 266 浏览 8 评论 0原文

我正在尝试在 Bash shell 中一次通过多个命令通过管道传输 awk 命令的输出,根据我的知识,我想到了这一点:

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

我希望对 awk 命令的结果进行计数和排序,如何我能做到吗? 即使有 &&命令它不起作用,它执行第一个命令然后退出。 我想这是我对 bash 的了解失败了。

提前致谢。

I'm trying pipe the output of an awk command through more than one command at once in a Bash shell, following my knowledge I'm coming up with this:

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

I want the result of the awk command to be both counted AND sorted, how can I accomplish that?
Even with && command it doesn't work, it does execute the first command and then exits.
I guess it is my knowledge of bash which is failing.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

渔村楼浪 2024-09-20 01:37:18

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

试试这个:

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

这会在 stderr 上输出行数,并在 stdout 上输出排序后的输出。如果您需要 stdout 上的行数,则可以省略 >&2,但随后它将传递给排序调用并(很可能)排序到顶部输出。

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

If you want to send output to two different commands in a single line, you'll need to do process substituion.

Try this:

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

This outputs the line count on stderr and the sorted output on stdout. If you need the line count on stdout, you can do that leave off the >&2, but then it will be passed to the sort call and (most likely) sorted to the top of the output.

EDIT: corrected description of what happens based on further testing.

放肆 2024-09-20 01:37:18

在这种情况下,你用 awk 来计数,为什么需要管道?不要让事情变得更复杂

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

in that case, do your counting in awk , why the need for pipes? don't make it more complicated

awk '$13 ~ /type/ {print $15;c++}END{print c} ' filename.txt | sort -u
奶气 2024-09-20 01:37:18

如果输出的大小不太适合内存,并且出于性能原因您不需要 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 的类似构造使用了 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 协进程一起使用。

If the size in the output is not too large to fit in memory and you don't need the wc and sort commands to work in parallel for performance reasons, here's a relatively simple solution:

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

That complication with the the extra a is in case the awk command might print some empty lines at the end of the input, which the $() construct would strip. You can easily choose which of sort or wc should appear first.


Here's a way that works with any POSIX shell (ash, bash, ksh, zsh, ...) but only on systems that have /dev/fd (which includes reasonably recent Linux, *BSD and Solaris). Like Walter's similar construction using the simpler method available in bash, ksh93 and zsh, the output of wc and the output of sort may be intermixed.

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

If you both need to deal with intermediate output that doesn't comfortably fit in memory and don't want to have the output of the two commands intermixed, I don't think there's an easy way in a POSIX shell, though it should be doable with ksh or zsh coprocesses.

浮光之海 2024-09-20 01:37:18

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

You want to use named pipes created with mkfifo in combination with tee. An example is at http://www.softpanorama.org/Tools/tee.shtml

黄昏下泛黄的笔记 2024-09-20 01:37:18

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

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

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

I think the bigger question is: what are you expecting the output to be?

If you're trying to do two things, then do two things:

awk '$13 ~ /type/ {print $15}' filename.txt > tempfile
wc -l < tempfile
sort -u < tempfile
rm tempfile
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文