2012-09-06 41 views
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等那样从中提取匹配项?

谢谢!

回答

3

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

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

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

注意[[:alnum:]]是一样的其他语言\w,但POSIX正则表达式没有后者。有关详细信息,请参见man re_format

+0

参见[参数替换]为高级Bash脚本指南(http://tldp.org/LDP/abs/html/parameter-substitution.html#PARAMSUBREF)部更多的扩展/替换语法。 [Manipulating Strings](http://tldp.org/LDP/abs/html/string-manipulation.html)也是值得一读的一节。 –

+0

完美的作品 - 谢谢。我唯一的问题是:有没有办法用“普通”正则表达式(即不是POSIX的)来做到这一点,所以我不必重新格式化正则表达式? – WackGet

+0

@WackGet使用除'sed'之外的工具,例如Perl或Bash本身。 – ephemient

3

在Bash中的${parameter/pattern/string}语法parameter expansion而不是正则表达式;它是一个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 
3

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

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

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

否则,你要依靠awk或者sed。

+1

实际上有两个常见的'重命名'程序:在Perl发行版中(可能预装在Ubuntu中)[rename](http://search.cpan.org/perldoc?rename),[rename](http:///linux.icydog.net/rename.php)在util-linux(-ng)(可能预先安装在Fedora中)。他们不同。还有'mmv'和其他许多... – ephemient

0

尝试这种情况:

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

是的。您将括号中的左右括号括起来。然后,你回应(当concateatation被要求时)你删除了什么,减去围绕什么是在parentehses开始的括号......虽然完全正确的'bash',错综复杂,难以阅读,并没有提供完整的答案OP。是的,我知道这是“uralt”。 – Cbhihe

相关问题