如何将一个命令的输出传递给多个命令?

如何将一个命令的输出传递给多个命令?

使用进程替换或通过分组和管道,可以传递输出(标准输出)一组命令作为另一个命令的输入。

例子 :

wc < <(echo hi;echo bye)
(echo hi; bye) | wc

但有相反的情况吗?

也就是说,有没有办法将一个命令的输出作为许多其他命令的输入?单线

就像是 :

cat testfile | wc | tail -n 5

不要从字面上理解管道)。在这里我尝试将的输出传递cat testfilewctail -n 5

另一个例子是:

得到句子的最后一个单词

echo "some random words"| wc -c | cut -f(out put of wc -c) (output of first echo)

答案1

快速回答。您可以使用tee >(what_to_do) >(another_thing_to_do)它来继续执行您想要执行的许多不同操作。

例子:

原始测试文件输出:

:~$ cat testfile.txt 
Device Model:     LITEONIT LCS-256M6S 2.5 7mm 256GB
Serial Number:    TW0XFJWX550854187616

添加命令后的输出tee

:~$ cat testfile.txt | tee >(tail -1) >(wc) >(awk '{print $3,$1,$2}')
Device Model:     LITEONIT LCS-256M6S 2.5 7mm 256GB
Serial Number:    TW0XFJWX550854187616
LITEONIT Device Model:
TW0XFJWX550854187616 Serial Number:
      2      10      91
Serial Number:    TW0XFJWX550854187616

tee 中的每个命令只是您在命令行上使用的常规命令,例如 add in>(head -1 | wc)也同样有效。

:~$ cat testfile.txt | tee >(tail -1) >(head -1 | wc)  >(awk '{print $3,$1,$2}')
Device Model:     LITEONIT LCS-256M6S 2.5 7mm 256GB
Serial Number:    TW0XFJWX550854187616
      1       7      52
LITEONIT Device Model:
TW0XFJWX550854187616 Serial Number:
Serial Number:    TW0XFJWX550854187616

awk或者您也可以通过使用with$NF和 a来抓取最后一行的最后一个字,wc如下所示:

:~$ cat testfile.txt | tail -1 | tee >(wc) >(awk '{print $NF}')
Serial Number:    TW0XFJWX550854187616
TW0XFJWX550854187616
      1       3      39

笔记:|在末尾添加管道命令可以覆盖使用tee命令中的多个命令。我这里有一些我一直在测试的例子:

示例 1(管道命令提取所有最后的字):

:~$ echo "This is just five words" | tee >(wc -l) >(wc -w) >(wc -c) | awk '{print $NF}'
words
24
5
1

示例 2(不显示 wc 命令的输出。管道命令抓取第 3 个字。):

:~$ echo "This is just five words" | tee >(wc -l) >(wc -w) >(wc -c) | awk '{print $3}'
just

示例 3(抓取 echo 行的第 3 个单词。Tee 命令。):

:~$ echo "This is just five words" | tee >(wc -l) >(wc -w) >(wc -c) >(awk '{print $3}')
This is just five words
just
24
5
1

示例 4(抓取 echo 行的最后一个字。Tee 命令。):

:~$ echo "This is just five words" | tee >(wc -l) >(wc -w) >(wc -c) >(awk '{print $NF}')
This is just five words
words
24
5
1

希望这可以帮助!

答案2

您需要tee将流拆分成几部分。尝试:

cat testfile | tee >(wc -l) >(wc -w) >(wc -c) | tail -n 5

笔记:

  • 如果多个进程(wctail)都写入标准输出:

    • 您可能会得到乱码输出。

    • 无法保证其输出的显示顺序。要查看此信息,请尝试sleep 1; wc -w作为第二个消费者。

  • tee如果任何目的地没有足够快地使用流,则将阻塞。这意味着目的地将以大致相同的速度(模数固定大小的缓冲)输入。没有简单的解决方法,唯一的选择是将流保存到文件中,然后单独将其提供给消费者。对于wctail这不是问题。

对于最后一句话,做法更简单:

echo "some random words" | awk '{print $NF}'

答案3

moreutils包提供了命令pee(管道和三通的合并,您想到了什么?),它正是用于执行这一操作。

对于您的第一个例子,您可以使用:

cat testfile | pee wc "tail -n 5"

第二个示例更复杂,因为您要将两个输入传递给最后一个命令。我可能会将其用作awk其他答案。

关联:https://joeyh.name/code/moreutils/

答案4

仅获取文件的前导部分和尾随部分:

[wolf]$ cat >foo
1
2
3
4
5
6
^d
[wolf]$ cat foo | tee >(head -2) >(tail -2) >/dev/null
1
2
5
6

相关内容