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/46740389/

相关文章:

c - 使用 GNU Autotools 获取 GCC 包含路径

PHP Cron.Hourly 需要 mysql 驱动程序

bash - 如何在交互式 shell 脚本中使 "echo"ed 行可编辑?

macos - 我怎样才能让我的 vim 表现得像我的猫?

c# - 为什么 C# 编译器不能告诉这个函数总是返回或抛出?

linux - 创建特定类型的文件

reactjs - 如何使用 HTTPS 启动 React 项目

linux - 如何在 bash shell 脚本中使用表中的命令结果值

c - 数组在循环中如何工作?

for-loop - 有没有办法控制 OpenMP parallel_for 构造的分区?