Замените строку в скрипте 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