如何为find命令的每次迭代执行bash代码?

时间:2013-12-02 15:35:45

标签: bash shell unix

使用它将为找到的每个文件执行grep:

find . -name "$FILE" 2>null | xargs grep "search_string" >> $grep_out

但是,如果我想为找到的每个文件执行自定义代码,而不是执行grep,该怎么办?我想以自己的方式解析每个文件,这是做这件事的动机。我可以在管道中编写代码吗?我应该使用管道执行单独的脚本吗?在查找下一个文件之前,是否可以扩展管道的范围以执行代码中的下一行?

4 个答案:

答案 0 :(得分:2)

有几种方法,各有利弊。除了anubhava的内联方法,您还可以使用-exec标志和自定义脚本。例如:

find . -name "$FILE" -exec /path/to/script.sh {} +

然后编写/path/to/script.sh,使其接受任意数量的文件参数。例如:

#!/bin/bash
for file in "$@"; do
   echo "$file"
done

这种方法可以在内联方法上重复使用,但效率较低。

{} +上的find业务将多个文件传递给脚本的单个调用,而不是多次启动脚本 - 节省了一些进程开销。如果您希望脚本为每个单个文件执行新鲜,请改用{} \;(在脚本中只需“$ 1”,不需要循环)。

"$@"位保留引用的文件名,这对于文件名中包含空格的情况很重要。

答案 1 :(得分:1)

您可以在BASH

中使用{strong>这样的 while loop
while read f; do
    # process files here
    echo "$f"
done < <(find . -name "$FILE")

sh一起使用(不支持流程替换):

find . -name "$FILE" | while read f; do
    # process files here
    echo "$f"
done

<强> Read more about process substitution

答案 2 :(得分:1)

find . -name "$FILE" 2>null -execdir /path/to/script.sh {} \;

这样,不再需要在某处创建for循环。

答案 3 :(得分:0)

您可以使用-exec选项(而不是xargs):

find . -name "$FILE" -exec ./test.sh {} \;

脚本test.sh包含您想要的任何内容。例如:

$ cat test.sh
#!/bin/bash

echo "name=$1"
grep "string" "$1"
$ cat test
string
string2
test
$ sudo find . -name "test" -exec ./test.sh {} \;
name=./test
string
string2