我该怎么办的foreach * .MP3文件递归在bash脚本?(How can I do fore

2019-08-21 09:40发布

下面的作品在当前文件夹中的罚款,但我想它扫描子文件夹以及。

for file in *.mp3

do

echo $file

done

Answer 1:

太多这些答案使用shell扩展存储一个查找的结果。 这是不是你应该做的掉以轻心。

比方说,我有30000首歌曲,这些歌曲的标题平均约为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在他们(或双击空格),管道中的发现到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变量aill认为他们是:

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使用空,或使用-d\0中,而参数BASH外壳读声明。



Answer 2:

有很多方法对皮肤这只猫。 我会用find命令自己的电话:

for file in $(find . -name '*.mp3') do
  echo $file
  TITLE=$(id3info "$file" | grep '^=== TIT2' | sed -e 's/.*: //g')
  ARTIST=$(id3info "$file" | grep '^=== TPE1' | sed -e 's/.*: //g')
  echo "$ARTIST - $TITLE"
done

如果你在你的文件名空间那么最好使用-print0选项来查找; 一种可能的方式是这样的:

find . -name '*.mp3' -print0 | while read -d $'\0' file
do
  echo $file
  TITLE=$(id3info "$file" | grep '^=== TIT2' | sed -e 's/.*: //g')
  ARTIST=$(id3info "$file" | grep '^=== TPE1' | sed -e 's/.*: //g')
  echo "$ARTIST - $TITLE"
done

或者你也可以保存和恢复IFS 。 感谢David W.的意见,特别是,对于指出的是, while循环版本也有,它会正确地处理大量文件的,而其扩展了第一个版本的利益$(find)成用于-loop会失败在某些时候工作,因为shell扩展是有限制的。



Answer 3:

find . -name *.mp3 -exec echo {} \;

字符串{}到处都在处理被当前文件名取代了它的参数发生的命令,不只是在争论它是孤独的,因为在发现的一些版本。

请检查发现男子作进一步的信息http://unixhelp.ed.ac.uk/CGI/man-cgi?find



Answer 4:

find . -name \*.mp3 | (
    while read file; do
        echo $file
    done
)


Answer 5:

这适用于大多数的文件名(包括空格),但不换行,制表符或双空格。

find . -type f -name '*.mp3' | while read i; do
   echo "$i"
done

这适用于所有文件名。

find . -type f -name '*.mp3' -print0 | while IFS= read -r -d '' i; do
   echo "$i"
done

但是,如果你只是想运行一个命令就可以使用xargs例子:

find . -type f -name '*.mp3' -print0 | xargs -0 -l echo


Answer 6:

听起来像是你正在寻找find命令。 我没有测试过这一点,但这些方针的东西:

files=(`find . -name *.mp3`)
for file in "${files[@]}"; do
    echo $file TITLE="id3info "$file" | grep '^=== TIT2' | sed -e 's/.*: //g'" ARTIST="id3info "$file" | grep '^=== TPE1' | sed -e 's/.*: //g'"
done

编辑:使用阵列使命令安全与名称中有空格的文件。



文章来源: How can I do foreach *.mp3 file recursively in a bash script?