Используйте regexp в bash для получения подстроки строки - PullRequest
0 голосов
/ 15 июня 2019

У меня есть строка, подобная следующей:

my-name-is-yes-111111.maybe.text.here?-34.34.34

Я хотел бы использовать регулярное выражение для захвата всего текста до первого экземпляра - [0-9], поэтому в этом случае я получу:

my-name-is-yes

Я собираюсь перенести это на ansible, поэтому он должен использовать регулярное выражение, а не sed, awk или что-то в этом роде.

Я использовал sed, чтобы придуматьчто-то, но опять же, мне нужно регулярное выражение:

echo $x | rev |cut -d. -f6 | rev | sed -e 's/-[0-9]*$//g'
my-name-is-yes

Проблема здесь может быть больше периодов, чем.6, что я должен был бы сократить.

Ответы [ 4 ]

2 голосов
/ 15 июня 2019

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

$ str='my-name-is-yes-111111.maybe.text.here?-34.34.34'
$ echo "${str%%-[[:digit:]]*}"
my-name-is-yes

, где ${<i>parameter</i>%%<i>word</i>} удаляет совпадение длин шаблона, до которого word расширяется от концарасширения parameter.

2 голосов
/ 15 июня 2019

Вы можете использовать расширение параметра оболочки для решения указанного вами теста. Вот пример:

# var=my-name-is-yes-111111.maybe.text.here?-34.34.34
# echo ${var%%\-[0-9]*}
my-name-is-yes

Если вам нужна эта переменная, вы можете назначить расширение вместо этого, то есть

var=my-name-is-yes-111111.maybe.text.here?-34.34.34
var2=${var%%\-[0-9]*}
echo $var2
my-name-is-yes

Вы даже можете перезаписать свое первое значение значением расширения,

var=my-name-is-yes-111111.maybe.text.here?-34.34.34
var=${var%%\-[0-9]*}
echo $var
my-name-is-yes

Операторы расширения параметров % и %% означают «удалить совпадающее значение с правой стороны переменной», тогда как %% означает удаление максимального совпадения с правой стороны.

Существуют также операторы расширения параметров # и ##, которые выполняют аналогичную функцию, но "удаляют совпадающие значения с левой стороны от значения переменной. IHTH

0 голосов
/ 15 июня 2019

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

s='my-name-is-yes-111111.maybe.text.here?-34.34.34'
regex='^([A-Za-z0-9-]*)-[0-9]'
if [[  "$s" =~ $regex ]]; then
  echo "${BASH_REMATCH[1]}";
else
  echo "No match!";
fi;

Выход: my-name-is-yes.

См. Bash demo и regex grpah :

enter image description here

Детали шаблона

  • ^ - начало строки
  • ([A-Za-z0-9-]*) - группа захвата # 1 (${BASH_REMATCH[1]} будет иметь это значение): 0 или более букв ASCII, цифр или - символов
  • - - дефис
  • [0-9] - цифра.
0 голосов
/ 15 июня 2019

Выражение, которое может извлечь наш желаемый результат, будет таким простым:

([A-Za-z-]+)(-[0-9].+)

и наши желаемые данные находятся в этой группе захвата: ([A-Za-z-]+).

Демо

Рекомендации

user3299633 значительно упростил это решение:

if [[ $x =~ ([[:alnum:]-]+)(-[[:digit:]].+) ]]; then echo ${BASH_REMATCH[1]}; fi
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...