从终端中的 id3v1 标签重命名文件
rename files from id3v1 tags in terminal
我有一个 mp3 文件目录,它们都命名为 1.mp3、2.mp3 等。
#dir with numbers for names
10.mp3 15.mp3 2.mp3 24.mp3 29.mp3 33.mp3 38.mp3 42.mp3 47.mp3 51.mp3 56.mp3 60.mp3 65.mp3 7.mp3 74.mp3 79.mp3 83.mp3 88.mp3 92.mp3
11.mp3 16.mp3 20.mp3 25.mp3 3.mp3 34.mp3 39.mp3 43.mp3 48.mp3 52.mp3 57.mp3 61.mp3 66.mp3 70.mp3 75.mp3 8.mp3 84.mp3 89.mp3 93.mp3
12.mp3 17.mp3 21.mp3 26.mp3 30.mp3 35.mp3 4.mp3 44.mp3 49.mp3 53.mp3 58.mp3 62.mp3 67.mp3 71.mp3 76.mp3 80.mp3 85.mp3 9.mp3 94.mp3
13.mp3 18.mp3 22.mp3 27.mp3 31.mp3 36.mp3 40.mp3 45.mp3 5.mp3 54.mp3 59.mp3 63.mp3 68.mp3 72.mp3 77.mp3 81.mp3 86.mp3 90.mp3 95.mp3
14.mp3 19.mp3 23.mp3 28.mp3 32.mp3 37.mp3 41.mp3 46.mp3 50.mp3 55.mp3 6.mp3 64.mp3 69.mp3 73.mp3 78.mp3 82.mp3 87.mp3 91.mp3 96.mp3
我写了一个 for 循环来使用 ffmpeg 从元数据中提取标题:
for x in *.mp3; do
ffmpeg -i $x ./$("ffmpeg -i $x 2>&1 |grep -E '^\s*title\s*\:\s.*$' |awk -F ' :' '{print }'".mp3
done
我没有提取标题并重命名文件,而是说文件“.mp3”已经存在,我想重写它吗?当我输入 y 重写这个新的“.mp3”时,同样的事情又发生了。
我通过将输出文件的完整路径放在双引号中而不只是标题提取命令
来解决这个问题
for x in *.mp3; do
ffmpeg -I $x "./$(ffmpeg -i $x 2>&1 |grep -E '^\s*title\s*\:\s.*$' |awk -F ' :' '{print }'
)".mp3
done
我的问题是,当我只将标题提取命令用引号括起来而不是整个路径时,为什么它会创建一个名为 .mp3 的新文件?
很抱歉,如果这有点冗长,我是堆栈溢出的新手
在命令替换$(command)
中,你不应该换行命令
用双引号作为 $("command")
特别是当命令包含时
options and/or 管道序列,因为双引号字符串是
视为单个命令。
请看
的区别
echo $("ls")
和
echo $("ls -la")
第一个有效,但第二个无效,因为 bash
解释
ls -la
作为单个命令,而不是 ls
命令后跟 -la
选项。
顺便说一句,如果你只是想重命名文件,而不是重新编码(这可能会降低质量),你可以
说:
for f in *.mp3; do
title=$(ffmpeg -i "$f" 2>&1 | awk '/title/ {sub(/.*title\s*:\s*/, ""); print; exit}')
mv -i -- "$f" "$title".mp3
done
最后一个 exit
用于极端情况,mp3 文件包含多个 title
元数据。
[更新]
正如@llogan 评论的那样,ffprobe
更能提取媒体信息
的文件。请改为尝试:
for f in *.mp3; do
title=$(ffprobe -v error -of csv=p=0 -show_entries format_tags=title "$f")
mv -- "$f" "$title".mp3
done
我有一个 mp3 文件目录,它们都命名为 1.mp3、2.mp3 等。
#dir with numbers for names
10.mp3 15.mp3 2.mp3 24.mp3 29.mp3 33.mp3 38.mp3 42.mp3 47.mp3 51.mp3 56.mp3 60.mp3 65.mp3 7.mp3 74.mp3 79.mp3 83.mp3 88.mp3 92.mp3
11.mp3 16.mp3 20.mp3 25.mp3 3.mp3 34.mp3 39.mp3 43.mp3 48.mp3 52.mp3 57.mp3 61.mp3 66.mp3 70.mp3 75.mp3 8.mp3 84.mp3 89.mp3 93.mp3
12.mp3 17.mp3 21.mp3 26.mp3 30.mp3 35.mp3 4.mp3 44.mp3 49.mp3 53.mp3 58.mp3 62.mp3 67.mp3 71.mp3 76.mp3 80.mp3 85.mp3 9.mp3 94.mp3
13.mp3 18.mp3 22.mp3 27.mp3 31.mp3 36.mp3 40.mp3 45.mp3 5.mp3 54.mp3 59.mp3 63.mp3 68.mp3 72.mp3 77.mp3 81.mp3 86.mp3 90.mp3 95.mp3
14.mp3 19.mp3 23.mp3 28.mp3 32.mp3 37.mp3 41.mp3 46.mp3 50.mp3 55.mp3 6.mp3 64.mp3 69.mp3 73.mp3 78.mp3 82.mp3 87.mp3 91.mp3 96.mp3
我写了一个 for 循环来使用 ffmpeg 从元数据中提取标题:
for x in *.mp3; do
ffmpeg -i $x ./$("ffmpeg -i $x 2>&1 |grep -E '^\s*title\s*\:\s.*$' |awk -F ' :' '{print }'".mp3
done
我没有提取标题并重命名文件,而是说文件“.mp3”已经存在,我想重写它吗?当我输入 y 重写这个新的“.mp3”时,同样的事情又发生了。 我通过将输出文件的完整路径放在双引号中而不只是标题提取命令
来解决这个问题for x in *.mp3; do
ffmpeg -I $x "./$(ffmpeg -i $x 2>&1 |grep -E '^\s*title\s*\:\s.*$' |awk -F ' :' '{print }'
)".mp3
done
我的问题是,当我只将标题提取命令用引号括起来而不是整个路径时,为什么它会创建一个名为 .mp3 的新文件?
很抱歉,如果这有点冗长,我是堆栈溢出的新手
在命令替换$(command)
中,你不应该换行命令
用双引号作为 $("command")
特别是当命令包含时
options and/or 管道序列,因为双引号字符串是
视为单个命令。
请看
echo $("ls")
和
echo $("ls -la")
第一个有效,但第二个无效,因为 bash
解释
ls -la
作为单个命令,而不是 ls
命令后跟 -la
选项。
顺便说一句,如果你只是想重命名文件,而不是重新编码(这可能会降低质量),你可以 说:
for f in *.mp3; do
title=$(ffmpeg -i "$f" 2>&1 | awk '/title/ {sub(/.*title\s*:\s*/, ""); print; exit}')
mv -i -- "$f" "$title".mp3
done
最后一个 exit
用于极端情况,mp3 文件包含多个 title
元数据。
[更新]
正如@llogan 评论的那样,ffprobe
更能提取媒体信息
的文件。请改为尝试:
for f in *.mp3; do
title=$(ffprobe -v error -of csv=p=0 -show_entries format_tags=title "$f")
mv -- "$f" "$title".mp3
done