今天我在玩Bash脚本时偶然发现了Perl。当我尝试删除多个文件名中的空格时,我找到了this帖子,这对我帮助很大。
经过大量的努力,我终于明白了重命名和替换命令及其语法。由于文件重复,我想尝试用“x”替换文件名末尾的所有“_(x)”。但是当我尝试自己做的时候,似乎没有用。我有以下代码的三个问题:
find -name "*_(*)." -type f | \
rename 's/)././g' && \
find -name "*_(*." -type f | \
rename 's/_(//g' 2>&1
答案 0 :(得分:2)
find -name "*_(*)." -type f | xargs rename 's/)././g'
find -name "*_(*." -type f | xargs rename 's/_(//g'
或者:
find -name "*_(*)." -type f -exec rename 's/)././g' {} +
find -name "*_(*." -type f -exec rename 's/_(//g' {} +
在这两种情况下,文件名都会添加到rename
的命令行中。实际上,rename
必须读取其标准输入才能发现文件名 - 而事实并非如此。
第一个find
是否找到了您想要的文件?是否需要图案末尾的点?正则表达式是否符合您的期望?好吧,让我们调试一些。
您可以使用更复杂的正则表达式在一个命令中完成所有操作:
find . -name "*_(*)" -type f -exec rename 's/_\((\d+)\)$/$1/' {} +
find
模式已更正为失去追踪.
的要求。如果在扩展名之前插入了_(x)
,那么您需要"*_(*).*"
作为find
的模式(并且您需要修改Perl正则表达式)。
Perl替代品需要解剖:
\(
匹配左括号。(
启动了一个捕获组。\d+
会查找“一个或多个数字”。)
会停止捕获组。这是第一个也是唯一一个,因此给出数字1。\)
匹配一个右括号。$
与文件名的末尾匹配。$1
将捕获组1的值放入替换文本中。在您的代码中,2>&1
将第二个rename
命令的错误消息发送到标准输出而不是标准错误。这真的没什么用。
你需要两个单独的教程;你不会找到一个涵盖Bash中的I / O重定向和Perl中的正则表达式的教程。
'官方'Perl正则表达式教程是:
perldoc perlretut
格式使用。Bash手册涵盖了I / O重定向,但它有些简洁: