Cha*_*lie 10 linux bash mp3 for-loop
以下在当前文件夹中工作正常,但我希望它也扫描子文件夹.
for file in *.mp3
do
echo $file
done
Run Code Online (Sandbox Code Playgroud)
这些答案中有太多使用shell扩展来存储查找结果.这不是你应该轻易做的事情.
假设我有30,000首歌曲,这些歌曲的标题平均大约30个字符.让我们暂时不进入白空间问题.
我的发现将返回超过1,000,000个字符,而且我的命令行缓冲区很可能不是那么大.如果我做了这样的事情:
for file in $(find -name "*.mp3")
do
echo "some sort of processing"
done
Run Code Online (Sandbox Code Playgroud)
问题(除了文件名中的空白区域)是你的命令行缓冲区将简单地从溢出中删除溢出find
.它甚至可能完全无声地失败.
这就是xargs
创建命令的原因.它确保命令行缓冲区永远不会溢出.它将xargs
根据需要执行命令以保护命令行缓冲区:
$ find . -name "*.mp3" | xargs ...
Run Code Online (Sandbox Code Playgroud)
当然,使用xargs
这种方式仍然会占用空白区域,但是现代实现xargs
并且find
有办法处理这个问题:
$ find . -name "*.mp3 -print0 | xargs --null ...
Run Code Online (Sandbox Code Playgroud)
如果您可以保证文件名中没有选项卡或\n
(或双空格),那么将find放入while循环更好:
find . -name "*.mp3" | while read file
do
Run Code Online (Sandbox Code Playgroud)
管道将文件发送到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.
Run Code Online (Sandbox Code Playgroud)
仍然会失败.该$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.
Run Code Online (Sandbox Code Playgroud)
为了解决这个问题,你必须find ... -print0
使用null作为输入分隔符.然后更改IFS
为使用null,或使用-d\0
BASH shell中while read语句中的参数.
有很多方法可以给这只猫上皮.我会自己调用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
Run Code Online (Sandbox Code Playgroud)
如果文件名中有空格,则最好使用该-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
Run Code Online (Sandbox Code Playgroud)
或者你可以保存和恢复IFS
.感谢David W.的评论,特别是指出while
循环版本还具有正确处理大量文件的好处,而第一个将a扩展$(find)
为for循环的版本将无法在某些方面工作,因为shell扩展有限制.
这适用于大多数文件名(包括空格),但不适用于换行符、制表符或双空格。
find . -type f -name '*.mp3' | while read i; do
echo "$i"
done
Run Code Online (Sandbox Code Playgroud)
这适用于所有文件名。
find . -type f -name '*.mp3' -print0 | while IFS= read -r -d '' i; do
echo "$i"
done
Run Code Online (Sandbox Code Playgroud)
但是如果您只想运行一个命令,您可以使用xargs
示例:
find . -type f -name '*.mp3' -print0 | xargs -0 -l echo
Run Code Online (Sandbox Code Playgroud)
Jos*_*osh -1
听起来您正在寻找 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
Run Code Online (Sandbox Code Playgroud)
编辑:使用数组使命令对于名称中带有空格的文件是安全的。
归档时间: |
|
查看次数: |
10554 次 |
最近记录: |