是否有一个标准工具可以根据命令执行结果过滤文本流?
grep
例如考虑一下。它可以基于正则表达式过滤文本流。但更普遍的问题是扩展过滤条件。例如,我可能想选择与某些条件匹配的所有文件(find
有大量可用的检查,但无论如何它都是一个子集),或者只是使用另一个程序来过滤我的数据。考虑这个管道:
produce_data | xargs -l bash -c '[ -f $0 ] && ping -c1 -w1 $1 && echo $0 $@'
它完全没有用,但它提供了一个通用的方法。我可以使用任何 bash oneliner 来测试每一行。在此示例中,我想要由现有文件和可访问主机组成的行。我想要一个标准工具,可以这样做:
produce_data | super_filter -- bash -c '[ -f $0 ] && ping -c1 -w1 $1'
它可以很容易地与以下内容一起使用find
:
find here | super_filter -- test -r
请注意它如何允许您使用通用工具来过滤文件,而不是find
我总是忘记的特定标志。
一个更现实的例子是查找具有特定符号的目标文件,这种工具会很有帮助。
因此super_filter
将允许任何条件检查器在流模式下运行。语法可能类似于 in xargs
or parallel
。
答案1
如果添加的话 GNU Parallel 不会工作吗&& echo
?
... | parallel 'test -r {} && echo {}'
答案2
while read
方法(纯bash)
while read
是逐行处理输入的常见习惯用法(如何循环遍历文件的行?)。echo
对原始输入行进行任何检查和有条件的操作。
... | while IFS= read -r line; do test -r "$line" && echo "$line"; done
特例:find
find
有一个-exec
执行任意操作并检查找到的文件的操作:
从man find
:
-exec command ; Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of `;' is encountered. The string `{}' is replaced by the current file name be‐ ing processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find. Both of these constructions might need to be escaped (with a `\') or quoted to protect them from expansion by the shell. See the EXAMPLES section for examples of the use of the -exec option. The specified command is run once for each matched file. The command is executed in the starting directory. There are unavoid‐ able security problems surrounding use of the -exec action; you should use the -execdir option instead.
例子:
find here -exec test -r {} \; -print
由于-exec
操作会覆盖默认-print
操作,因此-print
必须明确指定。 find(1) 手册页的 EXPRESSION 部分描述了此行为。如果您要应用进一步处理,请使用-print0
+xargs --null
而不是-print
。