以下在当前文件夹中工作正常,但我希望它也能扫描子文件夹。
for file in *.mp3
do
echo $file
done
最佳答案
这些答案中有太多使用 shell 扩展来存储查找结果。这不是你应该轻易做的事情。
假设我有 30,000 首歌曲,这些歌曲的标题平均在 30 个字符左右。我们暂时不要讨论空白 问题。
我的查找将返回超过 1,000,000 个字符,而且我的命令行缓冲区很可能没有那么大。如果我做了这样的事情:
for file in $(find -name "*.mp3")
do
echo "some sort of processing"
done
问题(除了文件名中的空格之外)是您的命令行缓冲区将简单地从 find
中删除溢出。它甚至可能完全无声地失败。
这就是创建 xargs
命令的原因。它确保命令行缓冲区永远不会溢出。它将根据需要多次执行 xargs
之后的命令以保护命令行缓冲区:
$ find . -name "*.mp3" | xargs ...
当然,以这种方式使用 xargs
仍然会在空白处阻塞,但是 xargs
和 find
的现代实现有一种处理方式这个问题:
$ find . -name "*.mp3 -print0 | xargs --null ...
如果您可以保证文件名中没有制表符或 \n
(或双空格),则将 find 传递到 while 循环中会更好:
find . -name "*.mp3" | while read file
do
管道会在命令行缓冲区满之前将文件发送到while read
。更好的是,read file
读取整行并将该行中找到的所有项目放入 $file
。它并不完美,因为 read
仍然会在空白处中断,因此文件名如:
I will be in \n your heart in two lines.mp3
I love song names with multiple spaces.mp3
I \t have \t a \t thing \t for \t tabs.mp3.
还是会失败。 $file
变量都将它们视为:
I will be in
your heart in two lines.mp3
I love song names with multiple spaces.mp3
I have a thing for tabs.mp3.
为了解决这个问题,您必须使用find ... -print0
将空值用作输入分隔符。然后将 IFS
更改为使用空值,或者在 BASH shell 的 while read 语句中使用 -d\0
参数。
关于linux - 如何在 bash 脚本中递归地执行 foreach *.mp3 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46740389/