Регулярные выражения, конец строки и Bashscript просто не будут работать вместе - PullRequest
0 голосов
/ 22 декабря 2011

Я сейчас пишу 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 \ $ также не работает.Я ничего не понимаю ...

Может кто-нибудь помочь мне заставить его работать так, как мне нужно?

PS [0-9] {3} вместо [0-9] [0-9] [0-9] также ломает его.Если кто-то знает, как его сократить, скажите, пожалуйста:)

Ответы [ 4 ]

2 голосов
/ 22 декабря 2011

Использование:

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 голос
/ 22 декабря 2011

$ не используется bash, bash использует префикс%:

echo ${filename/%_[0-9][0-9][0-9].jpg/}.${filename/*./}
0 голосов
/ 22 декабря 2011

Попробуйте ${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

Таким образом, всегда удаляя последний _, после которого идут любые цифры.

0 голосов
/ 22 декабря 2011

Я думаю, это то, что вы хотите:

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

Так что все _NNN будут заменены.Вывод выше: example2.jpg.jpg

...