在Bash中使用正则expression式和x = $ {…}重命名文件?

我有一堆包含括号中的前缀代码的文件。 我想把这些前缀变成后缀,就像这样:

Finance-(4BF)-001.doc --> Finance-001-4BF.doc Corporate-(K04)-001.doc --> Corporate-001-K04.doc 

我以前写了一个非常简单的VBScript在Windows机器上做到这一点,但现在我需要在Linux上做到这一点。 经过一番繁琐的search之后,我找不到一个简单而优雅的方法来将正则expression式应用于文件名,并使用正则expression式匹配对其进行重命名。

到目前为止,我有这样的:

 #!/bin/bash for i in *.doc do x=${i//[\(\)]/} echo "$i renames to: $x" done 

这个的输出是:

 Corporate-(K04)-001.doc renames to: Corporate-K04-001.doc Finance-(4BF)-001.doc renames to: Finance-4BF-001.doc 

我知道上面的正则expression式只是将括号()从文件名中剥离出来…但肯定必须有一种方法来匹配它们的内容(例如\((\w)\) ),然后在重命名命令(例如$1 )?

也是一个Linux新手,我不明白x=${...}在做什么,因为我不知道它叫什么,我不能谷歌它。 我认为这是应用正则expression式的stringi但在这种情况下,为什么我不能从中提取匹配,如$1$2等?

谢谢!

构造${...}被称为“参数扩展”,可以在Bash手册中找到。

替换功能是非常基本的,不支持反向引用( $1 )。 你可以使用sed来代替:

 x=$(sed -E 's/\(([[:alnum:]]+)\)-([[:alnum:]]+)/\2-\1/' <<< "$i") 

请注意, [[:alnum:]]与其他语言的\w相同,但POSIX正则表达式不具有后者。 有关详细信息,请参阅man re_format

Bash 参数展开中的${parameter/pattern/string}语法不是正则表达式; 它是一个glob(用#%特别处理)。

Bash的[[ =~ ]] 条件表达式采用正则表达式,将捕获的组放入${BASH_REMATCH[@]}数组中。

 #!/bin/bash for i in *.doc; do if [[ $i =~ ^(.*)-\((.*)\)-([^.]*)(..*)?$ ]]; then x="${BASH_REMATCH[1]}-${BASH_REMATCH[3]}-${BASH_REMATCH[2]}${BASH_REMATCH[4]}" echo "$i renames to: $x" fi done 

根据您正在运行的系统,应该有一个实际上是perl脚本的重命名实用程序,并允许您使用正则表达式。 我知道在较新的Ubuntu版本中,他们有这样的命令,而在我的Slackware发行版中,我没有这个命令。

但是,您可以尝试使用它,如下所示:

rename 's/-\((.{3})\)-(.{3})/-$2-$1/' *.doc

否则,你必须依靠sed或awk。

尝试这个:

 #!/bin/bash for i in *.doc; do x=${i#*(} x=${x%)*} echo "$i renames to: ${i%%-*}-$x-${i##*-}" done