find -exec 中的管道命令?

find -exec 中的管道命令?

假设我想查找所有.txt文件并搜索某个字符串。我会做:

find ./ -type f -name "*.txt" -exec egrep -iH 'something' '{}' \;

如果我想做更复杂的过滤,如下所示:

egrep something file.txt | egrep somethingelse | egrep other

里面找到-exec? (或类似)

请记住,我正在寻找一个可以在需要时轻松输入的解决方案。我知道这可以使用 shell 脚本通过几行来完成,但这不是我想要的。

答案1

如果您必须在 find 中执行此操作,则需要调用 shell:

find ./ -type f -name "*.txt" -exec sh -c 'grep -EiH something "$1" | grep -E somethingelse | grep -E other' sh {} \;

其他替代方案包括使用xargs

find ./ -type f -name "*.txt" | 
    xargs -I{} grep -EiH something {} | 
        grep -EiH somethingelse | 
            grep -EiH other

或者,对于任意文件名更安全(假设您find支持-print0):

find ./ -type f -name "*.txt" -print0 | 
    xargs -0 grep -EiH something {} | 
        grep -Ei somethingelse | 
            grep -Ei other

或者,您可以只使用 shell 循环:

find ./ -type f -name "*.txt" -print0 | 
    while IFS= read -d '' file; do 
        grep -Ei something "$file" | 
            grep -Ei somethingelse | 
                grep -Ei other
    done

答案2

编辑:这个答案是不优选,但留在这里是为了比较和说明 bash 脚本中潜在的危险陷阱。


您可以将bash(或另一个 shell)作为您的-exec命令:

find -type -f -name "*.txt" -exec bash -c 'egrep -iH something "{}" | egrep somethingelse | egrep other' \;

这样做的缺点之一是,随着命令变得更加复杂,它会产生更多嵌套引用问题的可能性。如果你想避免这种情况,你可以将其分解为一个for循环:

for i in $(find -type -f -name "*.txt"); do
  if egrep -iH something "$i" | egrep somethingelse | egrep other; then 
    echo "Found something: $i"
  fi
done

相关内容