使用基于Perl的重命名命令和Bash中的find



我今天在玩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重定向

最新更新