我正在寻找一种方法来重命名大量名称相似的文件,很像这个(与 Windows 相关的问题)除了我使用 *nix (分别是 Ubuntu 和 FreeBSD) 之外。
总而言之,在使用 shell(Bash、CSH 等)时,如何批量重命名多个文件,例如以下文件:
Beethoven - Fur Elise.mp3
Beethoven - Moonlight Sonata.mp3
Beethoven - Ode to Joy.mp3
Beethoven - Rage Over the Lost Penny.mp3
会改名成这样吗?
Fur Elise.mp3
Moonlight Sonata.mp3
Ode to Joy.mp3
Rage Over the Lost Penny.mp3
我想要这样做的原因是这些文件集合将放在名为“贝多芬”(即文件名的前缀)的目录下,而文件名本身包含这些信息将是多余的。
答案1
这Perl 的重命名实用程序会做你想做的事。
只需使用rename 's/Beethoven\ -\ //g' *.mp3
答案2
与 Linux/Unix 的许多事物一样,有多种方法可以做到!
有些可能会使用韓國(质量 mv)。
一些 Perl 包(较新的 Ubuntu 和 Debian)附带的重命名或预命名命令也可以执行此操作。
prename 's/Beethoven\ -\ //g' Beethoven*.mp3
请注意,Fedora 10 上的重命名工具与此程序不同,并且工作方式也不同。它是另一个软件包 util-linux-ng 的一部分,可以在以下位置找到这里。
我经常只是出于习惯而使用 shell for 循环(毕竟这样的工具并不总是存在)。
mkdir -p Beethoven
for x in Beethoven\ -\ *
do
mv "$x" Beethoven/"${x/Beethoven - /}"
done
这将创建 Beethoven 目录,然后将文件移动到该目录/文件名,其中文件名中的“Beethoven - ”被替换为空。
作为测试,之前:
$ ls
Beethoven - Fur Elise.mp3 Beethoven - Ode to Joy.mp3
Beethoven - Moonlight Sonata.mp3 Beethoven - Rage Over the Lost Penny.mp3
后:
$ ls Beethoven/
Fur Elise.mp3 Ode to Joy.mp3
Moonlight Sonata.mp3 Rage Over the Lost Penny.mp3
答案3
尝试这个解决方案,使用 grep 和 rename 的组合来实现。这是假设您有一大堆需要重命名的目录。如果只有几个,我会采用手动方法,为每个目录硬编码“Artist - ”模式。
# Rename any mp3 files in the directory hierarchy of type "a - b.mp3" to "b.mp3"
find . -name "*.mp3" -exec rename -n -v 's|^(.*/).*-\s*(.*)\s*$|$1$2|g' {} \;
解释寻找:
这寻找命令查找所有带有.mp3当前文件层次结构中的扩展,并调用传递给-执行对于每一个。请注意,在-执行,{}指的是传递的参数寻找(文件路径+名称)。\;
确保;
传递到改名而不是表明寻找命令。
上面给出的命令有-n(无操作)开关;因此它只会告诉您运行它时会发生什么。我建议您在运行一次并对所提出的结果感到满意之后,才运行不带 -n 开关的此命令。
现在来看看正则表达式。
^
匹配字符串的开头。$
匹配字符串的结尾。.
匹配任意字符。*
表示零个或多个前一个构造。例如.*
表示零个或多个字符。\s
代表任意空格字符。\S
代表任何非空格字符。- 其中的任何东西都会被捕获,并根据其位置
()
反映为$1
、 。$2
正则表达式:
- 在开始时寻找可选的目录结构,并在 $1 中捕获它:
(.*/)
- 跳过所有内容直到“
-
”:.*-
- 在 $2 中捕获字符串的其余部分(前导和尾随空格除外):
(.*)
- 将文件重写为 $1$2,即“/path/to/file/""filename.mp3”
这是我的测试运行:
/tmp/test$ ls -R
.:
a b c z-unknown.mp3
./a:
a3.mp3 a - longer title3.mp3 c.mp3 disc2
a - longer title2.mp3 a - long title.mp3 disc 1 the band - the title.mp3
./a/disc 1:
a - title1.mp3 a - title2.mp3
./a/disc2:
a - title1.mp3 a - title2.mp3
./b:
cd - ab - title3.mp3 cd - title1.mp3 cd - title2.mp3 c.mp3
./c:
c-pony2.mp4 c - pony3.mp3 c - pony4.mp3 c-pony.mp3
/tmp/test$ find . -name "*.mp3" -exec rename -v 's|^(.*/).*-\s*(.*)\s*$|$1$2|g' {} \;
./c/c-pony.mp3 renamed as ./c/pony.mp3
./c/c - pony4.mp3 renamed as ./c/pony4.mp3
./c/c - pony3.mp3 renamed as ./c/pony3.mp3
./z-unknown.mp3 renamed as ./unknown.mp3
./a/the band - the title.mp3 renamed as ./a/the title.mp3
./a/a - longer title2.mp3 renamed as ./a/longer title2.mp3
./a/a - longer title3.mp3 renamed as ./a/longer title3.mp3
./a/disc 1/a - title1.mp3 renamed as ./a/disc 1/title1.mp3
./a/disc 1/a - title2.mp3 renamed as ./a/disc 1/title2.mp3
./a/a - long title.mp3 renamed as ./a/long title.mp3
./a/disc2/a - title1.mp3 renamed as ./a/disc2/title1.mp3
./a/disc2/a - title2.mp3 renamed as ./a/disc2/title2.mp3
./b/cd - title1.mp3 renamed as ./b/title1.mp3
./b/cd - title2.mp3 renamed as ./b/title2.mp3
./b/cd - ab - title3.mp3 renamed as ./b/title3.mp3
/tmp/test$ ls -R
.:
a b c unknown.mp3
./a:
a3.mp3 c.mp3 disc 1 disc2 longer title2.mp3 longer title3.mp3 long title.mp3 the title.mp3
./a/disc 1:
title1.mp3 title2.mp3
./a/disc2:
title1.mp3 title2.mp3
./b:
c.mp3 title1.mp3 title2.mp3 title3.mp3
./c:
c-pony2.mp4 pony3.mp3 pony4.mp3 pony.mp3
正则表达式是一件棘手的事情,我在编写它们时犯了很多错误,因此我欢迎任何关于这个缺陷的意见。我知道我发现有不少人对此进行了测试。
答案4
zmv
zsh 重命名工具非常好。
# zmv "programmable rename"
# Replace spaces in filenames with a underline
zmv '* *' '$f:gs/ /_'
# Change the suffix from *.sh to *.pl
zmv -W '*.sh' '*.pl'
# lowercase/uppercase all files/directories
$ zmv '(*)' '${(L)1}' # lowercase
$ zmv '(*)' '${(U)1}' # uppercase