while read方法(纯bash)

while read方法(纯bash)

是否有一个标准工具可以根据命令执行结果过滤文本流?

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 xargsor 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

相关内容