linux - 如何在 bash 脚本中递归地执行 foreach *.mp3 文件?

标签 linux bash for-loop mp3

以下在当前文件夹中工作正常,但我希望它也能扫描子文件夹。

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 仍然会在空白处阻塞,但是 xargsfind 的现代实现有一种处理方式这个问题:

$ 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/15930407/

相关文章:

python - 如果我是 Python 新手,我应该使用哪个版本的 Python?

Bash set -u 允许单个未绑定(bind)变量

Bash 解压文件并在名称中添加时间戳

c++ - 如何在完整图的每条边上精确迭代一次?

C printf 在扫描下一个数字之前不会打印

linux - 在使用 xargs 和 fswatch 的命令之后运行命令

c - CLOCK_TAI 的纪元是什么?

python - Linux 上的 python httplib2 问题

bash shell 脚本语法错误

Python:打印而不覆盖打印的行