我最近发现了基于 perl 的rename
函数,但由于我对 perl 一无所知,所以无法正确使用它。我发现了很多关于这个主题的问题,但没有任何帮助我。
我想重命名
filename - y01m01 - extra.log
filename - y01m02 - extra.log
filename - y01m03 - extra.log
...
filename - y05m12 - extra.log
进入
filename-y01m01.log
filename-y01m02.log
filename-y01m03.log
...
filename-y05m12.log
我设法重命名为
filename-y01m01 - extra.log
filename-y01m02 - extra.log
filename-y01m03 - extra.log
...
filename-y05m12 - extra.log
使用但我不知道如何在最后rename 's/filename - y*/filename-y/ *.log
摆脱这个字符串。- extra
中的字符数- extra
不是固定的,取决于每个文件,因此我不能只替换扩展名前的八个字符。
我想解决方案是替换空格(包括空格)之后的所有内容,但我不知道如何编码。
感谢您的帮助。
答案1
该perl-rename
命令仅使用正则表达式。由于它是 Perl,因此它使用非常强大的 Perl 兼容正则表达式语言 (PCRE)。所以如果你想学习如何使用它,只需查找 PCRE 即可。
在本例中,您似乎想要删除文件名中的所有空格并删除字符串-extra
。您可以使用两个操作,只需用 分隔它们;
:
$ rename -n 's/ //g; s/-extra//' *.log
filename - y01m01 - extra.log -> filename-y01m01.log
filename - y01m02 - extra.log -> filename-y01m02.log
filename - y01m03 - extra.log -> filename-y01m03.log
filename - y05m12 - extra.log -> filename-y05m12.log
意思s/ //g
是“将所有空格替换为空”(因此,删除所有空格)。默认情况下,此处使用的替换运算符 ( s/old/new/options
) 将仅替换第一个匹配项。要使其替换所有匹配项,您需要“全局”选项 ( g
)。这就是为什么有一个g
in s/ //g
.
justs/-extra//
的意思是“将第一个匹配项替换为-extra
空”。
如果这符合您的要求,请再次运行它,但不要使用-n
.这使得rename
只需打印出它会做什么而无需实际执行。对于测试非常有用!
如果-extra
不是静态字符串,但可以更改,您可以删除最后一个之后-
直到下一个之前的所有内容.
:
$ rename -n 's/ //g; s/-[^-]*\././' *.log
filename - y01m01 - extra.log -> filename-y01m01.log
filename - y01m02 - extra.log -> filename-y01m02.log
filename - y01m03 - extra.log -> filename-y01m03.log
filename - y05m12 - extra.log -> filename-y05m12.log
在这里,将s/ //g
像以前一样删除所有空格,其s/-[^-]*\././
含义是“找到 a -
,然后找到其后最长的 0 个或多个-
以 a 结尾的非字符.
,并将整个内容替换为 a .
。我需要转义.
( \.
)在左侧,因为.
在未转义时表示“任何字符”,这在右侧不是问题。
答案2
您可以进行两次替换,一次替换第一个之后的部分-
,然后替换所有空格
rename -nv -- 's/-\s\w+[.]log$/.log/; s/\s+//g' *.log
一旦发现替换符合预期,就放下-n
标志。
答案3
提出这样的建议:
rename 's/(filename - y.*) - .*(\.log)/$1$2/' *.log