我试图找到所有以以下结尾的文件:
- 祖先-人类-奥德赛-预告片-720-1262.mp4
- 高科技潜水员-1080-1234.mp4
- 亚马逊潜水员-720-1323.mp4
并像这样重命名该文件:
- 720-1262.mp4
- 1080-1234.mp4
- 720-1323.mp4
我使用正则表达式但什么也没用,为什么?请问怎么了?
find . -regex '^.*-(([0-9])*-([0-9])*)\.mp4'
只有一个目录和这些文件,没有子目录。大约 300 个 .mp4 文件
答案1
GNUfind
支持多种正则表达式方言(该-regextype
选项允许您选择一种)。括号在其中一些字符中是特殊字符,需要进行反斜杠转义才能在其他字符中获得特殊含义。
根据在线文档,使用的默认方言-regex
是“POSIX basic”,而手册页网上说默认方言是“Emacs” 1。在这两个括号中,括号都需要进行反斜杠转义才能用作分组字符。
这些会起作用:
find . -regex '^.*-\(\([0-9]\)*-\([0-9]\)*\)\.mp4'
find . -regextype posix-extended -regex '^.*-(([0-9])*-([0-9])*)\.mp4'
然而,^
这里不需要(-regex
对文件名执行完全匹配)并且分组似乎没有必要;因此
find . -regex '.*-[0-9]*-[0-9]*\.mp4'
应该足够了(抛开与排序规则相关的潜在问题:[0-9]
可以匹配比 更多的东西[0123456789]
,具体取决于您的区域设置)。
关于重命名: 的 Perl 实现rename
(如果您可以使用)将是一个方便的选择。假设所有要重命名的文件都在当前工作目录中(不需要find
):
perl-rename -nv 's/.*-(\d*-\d*\.mp4)\Z/$1/' -- *
(其中\Z
相当于主题2$
末尾匹配的标准正则表达式)。
n
当您对命令的作用感到满意时,请删除(空运行)选项。
注意
- 这也将重命名
--.mp4
为-.mp4
:用于\d+
要求在最后一个数字之前和之后至少出现一个数字-
.*
还需要重命名隐藏文件
或者,使用 GNUfind
和标准mv
实用程序(也递归地下降到子目录):
find . -regex '.*-[0-9]*-[0-9]*\.mp4' -execdir sh -c '
for file; do
toremove=${file%-*-*.mp4}
echo mv -- "$file" "${file#"$toremove"-}"
done' mysh {} +
echo
当您对该命令的作用感到满意时,请删除。
¹ 作为斯蒂芬·查泽拉斯在评论中指出,已经在 savannah.org 上提交了一些关于文档中的不准确/不一致的错误报告:https://savannah.gnu.org/bugs/?58384,https://savannah.gnu.org/bugs/?52592,https://savannah.gnu.org/bugs/?61304
² Perl 的$
匹配位于主题末尾,而且也在主题末尾的换行符之前,因此,虽然在处理可能包含或不包含分隔符的文本行时很好,但\Z
在处理其他任何内容(例如文件名在这里。
答案2
和zsh
:
autoload zmv
zmv -n '(**/)*-(<->-<->.mp4)' '$1$2'
(-n
如果愿意,请删除以进行空运行)。