如何将两个不同命令的结果合并并通过管道传送到单个命令?

如何将两个不同命令的结果合并并通过管道传送到单个命令?

我想要合并(联合)两个不同命令的输出,然后将它们传送到单个命令。

举个愚蠢的例子:

我想要合并输出的命令:

cat wordlist.txt
ls ~/folder/*

进入:

wc -l

在这个例子中,如果 wordlist.txt 包含 5 行和 3 个文件,我想要wc -l返回 8。

$cat wordlist.txt *[magical union thing]* ls ~/folder/* | wc -l
8

我怎么做?

答案1

你的魔法联盟的事情是一个分号......和花括号:

    { cat wordlist.txt ; ls ~/folder/* ; } | wc -l

花括号仅将命令组合在一起,因此管道符号|会影响组合输出。

您还可以使用括号()括住命令组,这将在子 shell 中执行命令。这与花括号有一些细微的差别,例如,尝试以下内容:

    cd $HOME/Desktop ; (cd $HOME ; pwd) ; pwd
    cd $HOME/Desktop ; { cd $HOME ; pwd ; } ; pwd

您将看到,退出括号组后,所有环境变量(包括当前工作目录)都将被重置,但退出花括号组后则不会重置。

至于分号,替代方法包括&&||符号,它们分别仅在第一个命令成功或失败时有条件地执行第二个命令,例如

    cd $HOME/project && make
    ls $HOME/project || echo "Directory not found."

答案2

由于wc接受文件路径作为输入,您也可以使用流程替换:

wc -l <(cat wordlist.txt; ls ~/folder/*)

这大致相当于:

echo wordlist.txt > temp
ls ~/folder/* >> temp
wc -l temp

请注意,ls ~/folder/*如果存在子目录,还会返回子目录的内容(由于 glob 扩展)。如果您只想列出 的内容~/folder,则只需使用ls ~/folder

答案3

我也问了自己同样的问题,最后写了一个简短的剧本。

magicalUnionThing(我称之为append):

#!/bin/sh
cat /dev/stdin
$*

使该脚本可执行

chmod +x ./magicalUnionThing

你现在做

cat wordlist.txt |./magicalUnionThing ls ~/folder/* | wc -l

它能做什么:

  • 将标准输入发送到标准输出
  • 执行参数。$*以字符串形式返回所有参数。该命令的输出默认进入脚本标准输出。

因此 magicunionThing 的 stdout 将是其 stdin + 作为参数传递的命令的 stdout。

当然,还有其他更简单的方法,如其他答案所述。
在某些情况下,这种替代方案可能有用。

相关内容