使用正则表达式重命名文件并在Bash中使用x = $ {...}?

时间:2012-09-06 19:08:23

标签: regex linux bash shell

我有一堆文件,其中包含括号中的前缀代码。我想把这些前缀变成后缀,如下所示:

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

我以前写过一个非常简单的VBScript来在Windows机器上执行此操作,但现在我需要在Linux上执行此操作。经过一些乏味的搜索后,我找不到一种简单而优雅的方法将正则表达式应用于文件名并使用正则表达式匹配重命名。

到目前为止,我有这个:

#!/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

我知道上面的正则表达式只是从文件名中删除了括号()...但肯定必须有一种匹配其内容的方法(例如\((\w)\))然后在重命名中使用该匹配命令(例如$1)?

同样是Linux新手我不明白x=${...}正在做什么,因为我不知道它叫什么我不能谷歌它。我认为它正在将正则表达式应用于字符串i,但在这种情况下,为什么我不能像$1$2那样从中提取匹配项?

谢谢!

4 个答案:

答案 0 :(得分:3)

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

替换功能非常简单,不支持反向引用($1)。您可以改为使用sed

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

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

答案 1 :(得分:3)

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

Bash让[[ =~ ]] conditional expressions使用正则表达式,将捕获的组放入${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

答案 2 :(得分:3)

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

但是,您可以尝试按如下方式使用它:

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

否则,您必须依赖sed或awk。

答案 3 :(得分:0)

试试这个:

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