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

Sev*_*Tux 24 command-line bash

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

例子 :

wc < <(echo hi;echo bye)
(echo hi; bye) | wc
Run Code Online (Sandbox Code Playgroud)

但有相反的吗?

也就是说,有没有一种方法来发送一个命令的输出作为输入的许多其它命令在一个单行

就像是 :

cat testfile | wc | tail -n 5
Run Code Online (Sandbox Code Playgroud)

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

另一个例子是:

获取句子的最后一个单词

echo "some random words"| wc -c | cut -f(out put of wc -c) (output of first echo)
Run Code Online (Sandbox Code Playgroud)

Ter*_*nce 25

快速回答。您可以使用tee >(what_to_do) >(another_thing_to_do)来继续执行您的命令,以完成您想做的许多不同的事情。

例子:

原始测试文件输出:

:~$ cat testfile.txt 
Device Model:     LITEONIT LCS-256M6S 2.5 7mm 256GB
Serial Number:    TW0XFJWX550854187616
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

或者你也可以通过使用awkwith$NF和 a来获取最后一行的最后一个词,wc如下所示:

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

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

示例 1(管道命令拉出所有最后的话):

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

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

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

示例 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
Run Code Online (Sandbox Code Playgroud)

示例 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
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • 我喜欢 T 恤和咖啡!'-) (3认同)
  • 看我的回答。但更严重的是,`tee` 不知道消费者——它们是由处理线路的 `bash` 创建的。`bash` 所做的只是复制打开的文件描述符。除此之外,您还有多个消费者写入在同一文件上打开的文件描述符。内核会处理这个问题,但当然它们出现在 `bash` 命令行上的顺序不会是一个因素。 (2认同)

Mat*_*vid 17

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

cat testfile | tee >(wc -l) >(wc -w) >(wc -c) | tail -n 5
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 如果多个进程 ( wc, tail) 都在写入标准输出:

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

    • 无法保证其输出出现的顺序。要看到这一点,请尝试sleep 1; wc -w作为第二个消费者。

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

最后一句话,做起来更简单:

echo "some random words" | awk '{print $NF}'
Run Code Online (Sandbox Code Playgroud)


T. *_*ron 5

moreutils软件包提供了执行此操作的命令pee(管道和 tee 的合并,您有什么想法?)。

对于第一个示例,您将使用:

cat testfile | pee wc "tail -n 5"
Run Code Online (Sandbox Code Playgroud)

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

链接:https : //joeyh.name/code/moreutils/