我今天在玩Bash脚本时偶然发现了Perl。当我试图删除多个文件名中的空格时,我发现了这篇帖子,这对我帮助很大。
经过一番努力,我终于理解了重命名和替换命令及其语法。由于文件重复,我想尝试用"x"替换文件名末尾的所有"_(x)"。但当我尝试自己做的时候,它似乎根本不起作用。我有三个问题,代码如下:
- 为什么我运行它时没有执行任何操作
- 我使用重定向将成功笔记显示为错误,这样我就知道发生了什么。我做错了什么
- 经过大量研究,我仍然不完全理解Bash中的文件描述符和重定向,以及Perl中替代函数的语法。有人能给我一个好教程的链接吗
find -name "*_(*)." -type f |
rename 's/)././g' &&
find -name "*_(*." -type f |
rename 's/_(//g' 2>&1
您需要使用xargs
或使用find
执行命令的能力:
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
是否找到您想要的文件?图案末尾的点需要吗?正则表达式是否符合您的期望?好的,让我们也调试其中的一些。
您可以使用一个更复杂的regex:在一个命令中完成所有操作
find . -name "*_(*)" -type f -exec rename 's/_((d+))$/$1/' {} +
对CCD_ 6模式进行校正以丢失对尾随CCD_ 7的要求。如果在扩展之前插入_(x)
,则需要"*_(*).*"
作为find
的模式(并且需要修改Perl正则表达式)。
Perl替代品需要剖析:
(
匹配一个左括号(
启动一个捕获组d+
查找"一个或多个数字")
停止捕获组。它是第一个也是唯一一个,所以它被赋予了数字1)
匹配一个右括号$
与文件名的末尾匹配- 替换中的
$1
将捕获组1的值放入替换文本中
在您的代码中,2>&1
将第二个rename
命令中的错误消息发送到标准输出,而不是标准错误。这在这里真的没有多大帮助。
您需要两个单独的教程;您将找不到一个教程介绍Bash中的I/O重定向和Perl中的正则表达式。
"官方"Perl正则表达式教程是:
- perlretut,在您的机器上也可用作
perldoc perlretut
Bash手册涵盖了I/O重定向,但有些简洁:
- I/O重定向