正则表达式,行尾和Bash脚本将无法一起使用

时间:2011-12-22 12:00:52

标签: regex bash shell expression

我正在编写用于重命名文件的bash脚本。 每个文件看起来像 * _#。ext ,其中*可以是任何内容,#9位数字。在这个例子中,生病了3位数。

以下是它应该做的基本示例:

  

输入: example1_123.jpg
输出: example1.jpg

够简单吗?右:

#!/bin/bash
filename="example1_123.jpg"
echo ${filename/_[0-9][0-9][0-9]/}
  

输出:example1.jpg

这有效...只要输入不是这样的文件名: example2_123.jpg_987.jpg

该文件将重命名为example2.jpg_987.jpg而不是example2_123.jpg.jpg

我尝试使用$作为行尾,但这打破了它,因为$用于变量:

#!/bin/bash
filename="example2_123.jpg_987.jpg"
echo ${filename/_[0-9][0-9][0-9].jpg$/}.${filename/*./}
  

输出:example2_123.jpg_987.jpg.jpg   \ $也行不通。我很无能......

任何人都可以帮助我按照我需要的方式工作吗?

P.S。 [0-9] {3}而不是[0-9] [0-9] [0-9]也会打破它。如果有人知道如何缩短它,请说:)

4 个答案:

答案 0 :(得分:2)

使用:

target=$(echo $f | sed 's,_[0-9]\+\(\.[a-z]\+\)$,\1')

这将做你想要的。

fg@erwin ~ $ f=example2_123.jpg_987.png
fg@erwin ~ $ target=$(echo $f | sed 's,_[0-9]\+\(\.[a-z]\+\)$,\1,')
fg@erwin ~ $ echo $target
example2_123.jpg.png
fg@erwin ~ $ f=example1_123.png
fg@erwin ~ $ target=$(echo $f | sed 's,_[0-9]\+\(\.[a-z]\+\)$,\1,')
fg@erwin ~ $ echo $target
example1.png

如果$(...)中有空格名称,请使用双引号括号$f

这是sed,因此是一个经典的正则表达方言,因此分组,替代和量词(除了*)都需要先加上反斜杠...“规范”正则表达式确实是:

_[0-9]+(\.[a-z]+)$

答案 1 :(得分:1)

bash不使用

$,bash使用%前缀:

echo ${filename/%_[0-9][0-9][0-9].jpg/}.${filename/*./}

答案 2 :(得分:0)

我认为这就是你想要的:

filename="example2_123.jpg_987.jpg"
echo ${filename//_[0-9][0-9][0-9]/}

所有_NNN都将被替换。上面的输出是:example2.jpg.jpg

答案 3 :(得分:0)

在此示例中尝试${filename%_[0-9]*.*}.${filename##*.}"

for filename in example1_123.jpg example2_123.jpg_987.jpg example2_4.jpg_1.jpg ; do
    echo "$filename -> ${filename%_[0-9]*.*}.${filename##*.}"
done

这将输出

example1_123.jpg -> example1.jpg
example2_123.jpg_987.jpg -> example2_123.jpg.jpg
example2_4.jpg_1.jpg -> example2_4.jpg.jpg

因此总是删除最后的_后跟任何数字。