如何在bash脚本中处理find的结果?

时间:2010-01-18 15:22:19

标签: bash find

我正在尝试使用数组来使用find命令存储文件名列表。

由于某些原因,该阵列无法在学校使用的bash中工作,但我的程序在我自己的笔记本电脑上工作。

所以我想知道是否有另一种方法可以做到这一点,这就是我所拥有的:

array = (`find . -name "*.txt"`)  #this will store all the .txt files into the array

然后我可以使用cat命令访问数组项并复制所有文件。

有没有其他方法可以不使用数组?

6 个答案:

答案 0 :(得分:108)

你可以使用类似的东西:

find . -name '*.txt' | while read line; do
    echo "Processing file '$line'"
done

E.g。制作副本:

find . -name '*.txt' | while read line; do
    echo "Copying '$line' to /tmp"
    cp -- "$line" /tmp
done

HTH

答案 1 :(得分:18)

我遇到了JohannesWeiß解决方案的问题,如果我只是做一个回声,它将适用于完整的文件列表。但是,如果我尝试在下一行运行ffmpeg,脚本将只处理它遇到的第一个文件。我假设有一些IFS有趣的业务,因为管道,但我无法弄清楚,并用一个for循环运行:

for i in $(find . -name '*.mov' ); 
do
    echo "$i"
done

答案 2 :(得分:7)

只是不要在等号周围放置空格:

ar=($(find . -name "*.txt"))

如果可能,请避免使用反引号,因为它们已被弃用。它们很容易与叛逆者混淆,特别是在字体不好的情况下,并且它们不能很好地嵌套。

在大多数情况下,如果直接使用-exec,-execdir,-ok或-okdir迭代查找结果,则最佳服务。

对于文件名或换行符和制表符中的空白,for和while循环很难做到。

find ./ -name "*.txt" -exec grep {} ";"

{}不需要屏蔽。 您经常会看到一个组合find / xargs,它也会启动一个额外的过程:

find ./ -name "*.txt" | xargs grep {} ";"

答案 3 :(得分:5)

我认为starpause有最干净的解决方案,但是当路径中有空格时它会失败。通过设置IFS可以解决此问题。因此,正确的答案是:

IFS=$'\n'
for i in $(find . -name '*.mov' ); 
do
    echo "$i"
done
unset IFS

您取消设置IFS以重置IFS的行为以及$中需要IFS=$'\n'的原因,请参阅https://unix.stackexchange.com/questions/184863/what-is-the-meaning-of-ifs-n-in-bash-scripting

答案 4 :(得分:3)

find . -name '*.txt' | while IFS= read -r FILE; do
    echo "Copying $FILE.."
    cp "$FILE" /destination
done

答案 5 :(得分:0)

另一种变体来改变使用子shell的while循环内的一些变量

concat=""

while read someVariable
do
    echo "someVariable: '$someVariable'"
    concat="$concat someVariable")
done < <(find "/Users/alex" -name "*.txt")

echo "concat: '$concat'"