Замените строку в скрипте bash с помощью регулярных выражений для Linux и AIX

У меня есть скрипт bash, который я копирую и запускаю на серверах Linux и AIX.
Этот скрипт получает параметр "name", который представляет имя файла, и мне нужно манипулировать этим именем с помощью регулярных выражений (цель неактуальна и очень трудно объяснить).
От параметра name мне нужно взять начало до первого символа "-", за которым следует цифра, а затем сопоставить его с последним "." символ до конца строки.

Например:

имя: abcd-efg-1.23.4567-8.jar станет: abcd-efg.jar
имя: abc123-abc3.jar останется: abc123-abc3.jar
имя: abc-890.jar станет: abc.jar

Я пробовал несколько вариантов:

name=$1
regExpr="^(.*?)-\d.*\.(.*?)$/g"
echo $name 
echo $(printf ${name} | sed -e $regExpr)

Также я не могу использовать sed -r (видно на некоторых примерах), потому что AIX sed не поддерживает флаг -r.

Последняя строка, конечно, проблема; Я думаю, что мне нужно как-то использовать $1 + $2 заполнители, но я не могу понять, как это правильно.

Как я могу изменить свое регулярное выражение так, чтобы оно делало то, что я хочу?

4 ответа

Решение

Учитывая файл:

abcd-efg-1.23.4567-8.jar
abc123-abc3.jar
abc-890.jar

Это способ изменить имена, которые вы даете:

$ sed 's/\(.\?\)-[0-9].*\(\.[a-z]*\)$/\1\2/' file
abcd-efg.jar
abc123-abc3.jar
abc.jar

Что эквивалентно (если бы вы могли использовать -r):

$ sed -r 's/(.?)-[0-9].*(\.[a-z]*)$/\1\2/' file
abcd-efg.jar
abc123-abc3.jar
abc.jar
  • Это все до - + digit и "магазины" в \1,
  • Достает с прошлого . + letters и "магазины" в \2,
  • Наконец он печатает эти блоки обратно.

Обратите внимание, что расширение также может быть получено с basename встроенный или с чем-то вроде `"${line##*.}".

В sed вы можете просто использовать следующее.

#!/bin/sh
STRING=$( cat <<EOF
abcd-efg-1.23.4567-8.jar
abc123-abc3.jar
abc-890.jar
EOF
)
echo "$STRING" | sed 's/-[0-9].*\(\.[^.]\+\)$/\1/'
# abcd-efg.jar
# abc123-abc3.jar
# abc.jar

Это соответствует дефису, за которым следует число и все после, и заменяется расширением файла.

Или вы можете рассмотреть возможность использования однострочного Perl:

echo "$STRING" | perl -pe 's/-\d.*(?=\.[^.]+$)//'
# abcd-efg.jar
# abc123-abc3.jar
# abc.jar

Вы можете использовать это:

perl -F'(-(?:\d)|\.)' -ane 'print "$F[0].$F[$#F]"'

Делит вход на любой - с последующей цифрой или любой ., Затем печатается первое поле, за которым следует точка, за которой следует последнее поле.

Тестирование это:

$ cat file
abcd-efg-1.23.4567-8.jar
abc123-abc3.jar
abc-890.jar
$ perl -F'(-(?:\d)|\.)' -ane 'print "$F[0].$F[$#F]"' file
abcd-efg.jar
abc123-abc3.jar
abc.jar

После успешного сопоставления регулярному выражению perl будет захватывать все, что совпадает в скобках ( ..), как $1, $2 и т. д.

$ perl -e 'my $arg = $ARGV[0]; $arg =~ /^(.*?)-\d.*\.(.*?)$/; print "$1.$2\n"; ' abc-890.jar
abc.jar
Другие вопросы по тегам