Answers:
你神奇的结合是分号...和花括号:
{ 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."
{ list; }
是复合命令。From bash(1)
:list在当前的shell环境中简单地执行。列表必须以换行符或分号终止。[..]返回状态是列表的退出状态。
man bash
从命令行键入并浏览它。
wordlist.txt
不存在,则来自的错误cat
将出现在标准错误上,但不会出现在标准输出上,因此wc -l
不会从中计算任何行。~/folder
不存在的情况相同。可以2> /dev/null
在每个命令及其分号之间添加一个以防止标准错误产生噪音,但是除了难看之外,错误消息对于计数行无害。
由于wc
接受文件路径作为输入,因此您还可以使用进程替换:
wc -l <(cat wordlist.txt; ls ~/folder/*)
这大致相当于:
echo wordlist.txt > temp
ls ~/folder/* >> temp
wc -l temp
注意,ls ~/folder/*
如果有的话,它还会返回子目录的内容(由于全局扩展)。如果只想列出的内容~/folder
,请使用ls ~/folder
。
wc -l
只是一个虚构的示例,我实际上是将其传递到没有此选项的更复杂的示例中。
cat
接受文件参数,因此可以使用cat <(cat wordlist.txt; ls wordlist.txt) | wc -l
甚至cat wordlist.txt <(ls wordlist.txt) | wc -l
。这当然很丑陋,但是它展示了命令行工具的无限可能性。
ls ~/folder/
if ~/folder
符号链接ls
列出其目标的内容,而不是链接本身。顺便说一句,所有ls
命令都应跟在后面,-1
以便每行打印一个文件,这wc -l
是计数文件的有效方法。
-1
它的隐含含义是输出不是终端而是管道。
我在问自己同样的问题,最后写了一个简短的脚本。
magicalUnionThing
(我称之为append
):
#!/bin/sh
cat /dev/stdin
$*
使该脚本可执行
chmod +x ./magicalUnionThing
你现在做
cat wordlist.txt |./magicalUnionThing ls ~/folder/* | wc -l
它能做什么:
$*
以字符串形式返回所有参数。默认情况下,该命令的输出将转到脚本标准输出。因此,magicalUnionThing的标准输出将是作为参数传递的命令的标准输入+标准输出。
当然,还有其他更简单的方法。
在某些情况下,此替代方法可能有用。