4

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

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

4 回答 4

3

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

替换功能非常基本,不支持反向引用 ( $1)。您可以sed改用:

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

请注意,这与其他语言[[:alnum:]]相同\w,但 POSIX 正则表达式没有后者。详情请参阅man re_format

于 2012-09-06T19:24:24.483 回答
3

${parameter/pattern/string}Bash参数扩展中的语法不是正则表达式;它是一个球体(#经过%特殊处理)。

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
于 2012-09-06T19:28:52.600 回答
3

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

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

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

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

于 2012-09-06T19:33:04.890 回答
0

试试这个:

#!/bin/bash
for i in *.doc; do
  x=${i#*(}
  x=${x%)*}
  echo "$i renames to: ${i%%-*}-$x-${i##*-}"
done
于 2012-09-06T19:34:19.453 回答