我正在尝试使用数组来使用find
命令存储文件名列表。
由于某些原因,该阵列无法在学校使用的bash中工作,但我的程序在我自己的笔记本电脑上工作。
所以我想知道是否有另一种方法可以做到这一点,这就是我所拥有的:
array = (`find . -name "*.txt"`) #this will store all the .txt files into the array
然后我可以使用cat命令访问数组项并复制所有文件。
有没有其他方法可以不使用数组?
答案 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'"