我想要合并(联合)两个不同命令的输出,然后将它们传送到单个命令。
举个愚蠢的例子:
我想要合并输出的命令:
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。
当然,还有其他更简单的方法,如其他答案所述。
在某些情况下,这种替代方案可能有用。