我有一个有趣的问题,我希望可以通过shell命令轻松解决。我有一个目录树,目录名称是有意义的,每个目录中有几个文件,包括.mp3文件。
我想批量重命名所有mp3文件以匹配目录名称。
例如,高级目录如下所示:
Seans-iMac% ls
2006.James Lovelock: Gaia’s Revenge
2006.Religion and stem cell research
2006.Stephen Schneider
2006.Tony Judt: Post-war Europe since 1945
2006.Water management
2007.'Here, Bullet'
2007.Alan Bennett
每个子目录的内容都是相似的,例如:
Seans-iMac% cd "2006.Religion and stem cell research"
Seans-iMac% ls
details.txt lnl_20060605.mp3 synopsis.txt
我想将其更改为:
Seans-iMac% ls
details.txt 2006.Religion and stem cell research.mp3 synopsis.txt
我尝试了 for 循环,但似乎无法正确获取参数。为了使它更复杂,目录名称有空格,有些有单引号。
答案 0 :(得分:3)
如果你确定每个子目录中最多只有一个mp3文件,那么应该这样做:
for i in *; do mv "$i"/*.mp3 "$i/$i.mp3"; done
请注意处理空格的双引号。
答案 1 :(得分:2)
for d in 2???.*
do
mv "$d"/*.mp3 "$d/$d.mp3"
done
glob模式生成您感兴趣的目录名称,保留名称中的空格。 mv
命令假定子目录中只有一个.mp3
文件,因此第一个参数将扩展为正确的文件名(空格将再次保留),第二个参数具有所需的形成。请注意,*.mp3
在双引号字符串之外;这允许文件名扩展。请注意,目录名称(可能包含空格)始终位于双引号内,以避免丢失空白。
请谨慎使用glob以外的机制来生成目录名称。并不是说它们不能被使用;只需要小心。请注意,包含换行符的目录名称比空格更容易出问题;我将重命名这些目录,使它们不包含换行符(同样适用于包含换行符的文件名)。名称中的前导和尾随空白也可能存在问题。
答案 2 :(得分:2)
我的印象是你使用tcsh作为shell。 由于我不是一个大专家,因此以下产生一个bash shell并使用bash语法。
bash -c 'find /path/to/root/dir -name \*.mp3 | while read file; do d=`dirname "$file"`; b=`basename "$d"`; echo mv -v "$file" "$d/$b.mp3";done'
这不会做任何修改,它只是回应将要执行的命令。如果在仔细检查后确实按照您的意愿执行操作,请删除echo
命令前面的mv
。
这与上述限制相同,如果目录中有多个mp3文件,则最后一个(字母)文件将具有directory.mp3的名称,所有其他mp3文件将被覆盖(读取) :迷路了。
这种情况的不同之处在于文件夹的结构可以嵌套,而不一定是一个级别。