下面的作品在当前文件夹中的罚款,但我想它扫描子文件夹以及。
for file in *.mp3
do
echo $file
done
下面的作品在当前文件夹中的罚款,但我想它扫描子文件夹以及。
for file in *.mp3
do
echo $file
done
太多这些答案使用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外壳读声明。
有很多方法对皮肤这只猫。 我会用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扩展是有限制的。
find . -name *.mp3 -exec echo {} \;
字符串{}
到处都在处理被当前文件名取代了它的参数发生的命令,不只是在争论它是孤独的,因为在发现的一些版本。
请检查发现男子作进一步的信息http://unixhelp.ed.ac.uk/CGI/man-cgi?find
find . -name \*.mp3 | (
while read file; do
echo $file
done
)
这适用于大多数的文件名(包括空格),但不换行,制表符或双空格。
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
听起来像是你正在寻找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
编辑:使用阵列使命令安全与名称中有空格的文件。