在从备份导入我的音乐文件期间(由于默认命名方案rhythmbox),我弄乱了文件名。现在看起来像:
00 - American Pie.ogg.ogg.ogg.ogg
00 - American Pie.ogg.ogg.ogg.ogg.ogg
00 - another brick in the wall.ogg.ogg.ogg.ogg
00 - another brick in the wall.ogg.ogg.ogg.ogg.ogg
00 - candle_in_the_wind.ogg.ogg.ogg.ogg
00 - candle_in_the_wind.ogg.ogg.ogg.ogg.ogg
Run Code Online (Sandbox Code Playgroud)
虽然文件应该看起来像
American Pie.ogg
another brick in the wall.ogg
candle_in_the_wind.ogg
Run Code Online (Sandbox Code Playgroud)
我有(从wc -l)3096 个这样的文件。如何以批处理模式恢复它?我已经尝试rename并mmv工作,如该问题的 ans 中给出的那样,但没有工作(rename语法问题,并且 for mmv,存在冲突)。
请问有什么帮助吗?
使用 perl-rename(这是通常称为 的两种工具rename之一;另一种使用非常不同的语法,不能一步完成):
rename -f 's/00 - ([^.]*).*/$1.ogg/' *.ogg
Run Code Online (Sandbox Code Playgroud)
该-f或--force选项使得重命名覆盖任何现有文件。
第二部分是 perl 风格的正则表达式替换。基本语法是s/replacethis/withthis/The pattern to match -- 00 - ([^.]*).*-- 将匹配所有名称与您的问题中类似的 *.ogg 文件。00 --- 显然,这只是匹配每个文件名开头的模式。([^.]*)是正则表达式的核心。[^.]将匹配任何不是 a 的单个字符.,而*表示“任意数量的前一个事物”,因此[^.]*表示“任意数量的任何不是.'的任何字符”。括号标出一个捕获组(稍后会详细介绍)。在正则表达式中,.表示“任何字符”(如果你想在替换的这一侧有一个文字点,你必须将它转义,如:)\.,所以最后.* 表示“任意数量的任意字符”。
在替换命令的第二部分中,$1表示“第一个捕获组”——也就是说,包含在第一对括号内的那个(看到了吗?告诉过你我会回来的)。该.ogg手段文字“.OGG” -对替代的这一面,你也不需要逃避的点。
所以,粗略地翻译成英文,'s/00 - ([^.]*).*/$1.ogg/'就是告诉rename“取“00 -”,然后是(任意数量的不是点的字符),然后是任意数量的字符;并将其替换为括号内的字符和“.ogg.”'。
在某些系统上,会调用 perl-rename prename(当rename被上述其他程序采用时)。在某些系统上它根本不可用:(
对于递归,您可以执行以下操作之一:
shopt -s globstar ## assuming your shell is bash
rename 's/00 - ([^.]*).*/$1.ogg/' **/*.ogg
Run Code Online (Sandbox Code Playgroud)
或者:
find . -name '*.ogg' -exec rename 's/00 - ([^.]*).*/$1.ogg/' {} +
Run Code Online (Sandbox Code Playgroud)
小智 0
ls -1|while read f; do
newfile=$(echo $f|sed -e 's/\(\.ogg\)*$/.ogg/')
mv "$f" "$newfile"
done
Run Code Online (Sandbox Code Playgroud)