bash - 我可以做什么:find .... -exec this && that?

bash - 我可以做什么:find .... -exec this && that?

有没有一种方法可以逻辑地组合调用的两个 shell 命令查找-执行

例如打印出所有.csv包含字符串 foo 及其出现次数的文件我想做:

find . -iname \*.csv -exec grep foo {} && echo {} \;

巴什抱怨“缺少‘-exec’参数”

答案1

-exec是一个运行命令(不是 shell)并计算结果的谓词真的或者错误的基于命令的结果(零或非零退出状态)。

所以:

find . -iname '*.csv' -exec grep foo {} \; -print

打印grep如果在文件中找到 foo,则为文件路径。-print您可以使用另一个-exec谓词或任何其他谓词来代替

find . -iname '*.csv' -exec grep foo {} \; -exec echo {} \;

另请参阅!-o查找运算符以获取否定和或者

或者,您可以启动 shell:

find . -iname '*.csv' -exec sh -c '
   grep foo "$1" && echo "$1"' sh {} \;

或者避免为每个文件启动 shell:

find . -iname '*.csv' -exec sh -c '
  for file do
    grep foo "$file" && echo "$file"
  done' sh {} +

答案2

您面临的问题是 shell 首先解析命令行,并看到两个由&&运算符分隔的简单命令:find . -iname \*.csv -exec grep foo {}, 和echo {} \;。引用&&( ) 会绕过它find . -iname \*.csv -exec grep foo {} '&&' echo {} \;,但现在执行的命令find类似于grep带有参数foowibble.csv&&echowibble.csv您需要指示find运行一个解释该&&运算符的 shell:

find . -iname \*.csv -exec sh -c 'grep foo "$0" && echo "$0"' {} \;

请注意,后面的第一个参数sh -c SOMECOMMAND$0,不是$1

您可以通过将命令调用与-exec … +.为了便于处理,请传递一些虚拟值,以便$0枚举"$@"文件名。

find . -iname \*.csv -exec sh -c 'for x in "$@"; do grep foo "$x" && echo "$x"; done' \ {} +

如果 shell 命令只是由 分隔的两个程序&&find则可以自行完成这项工作:编写两个连续的-exec操作,并且仅当第一个操作以状态 0 退出时才会执行第二个操作。

find . -iname \*.csv -exec grep foo {} \; -exec echo {} \;

(我假设grepecho只是为了说明目的,-exec echo可以用 和 替换-print,结果输出无论如何都不是特别有用。)

答案3

在这个具体情况下我会这样做:

find . -iname \*.csv -exec grep -l foo \{\} \;

或者如果你有确认:

ack -al -G '.*\.csv' foo

要回答您的实际问题,类似这样的事情可能会起作用:

find . -iname \*.csv -exec sh -c "grep foo {} && echo {}" \;

相关内容