重命名文件以匹配目录名称

时间:2013-03-11 13:44:16

标签: shell unix

我有一个有趣的问题,我希望可以通过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 循环,但似乎无法正确获取参数。为了使它更复杂,目录名称有空格,有些有单引号。

3 个答案:

答案 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文件将被覆盖(读取) :迷路了。

这种情况的不同之处在于文件夹的结构可以嵌套,而不一定是一个级别。