0

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

4

3 回答 3

3

如果您确定每个子目录中最多有一个 mp3 文件,则应该这样做:

for i in *; do mv "$i"/*.mp3 "$i/$i.mp3"; done

注意处理空格的双引号。

于 2013-03-11T13:58:28.277 回答
2
for d in 2???.*
do
    mv "$d"/*.mp3 "$d/$d.mp3"
done

glob 模式生成您感兴趣的目录名称,并在名称中保留空格。该命令假定子目录mv中只有一个文件,因此第一个参数将扩展为正确的文件名(将再次保留空格),第二个参数具有所需的形式。.mp3请注意,*.mp3在双引号字符串之外;这允许文件名扩展。请注意,目录名称(可能包含空格)总是在双引号内以避免丢失空格。

在使用 glob 以外的机制生成目录名称时要小心。并不是不能使用它们;只是需要这种照顾。请注意,包含换行符的目录名称往往比空格更成问题;我会重命名这些目录,使它们不包含换行符(同样适用于包含换行符的文件名)。名称中的前导和尾随空格也可能有问题。

于 2013-03-11T13:58:41.833 回答
2

我的印象是您使用 tcsh 作为外壳。由于我不是一个大专家,下面会生成一个 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

This has the same limitations of the above ones, if there is more than one mp3 files in the directory, the last (alphabetical) file will have the name of the directory.mp3 and all other mp3 files will be overwritten (read: lost).

The difference in this case is that the structure of the folders can be nested and not necessarily in one level.

于 2013-03-11T15:18:37.863 回答