bash регулярное выражение сопоставляет необязательную подстроку с разделителями группы - PullRequest
0 голосов
/ 17 января 2019

В основном я хочу разобрать записи журнала в следующем формате:

a1 b2 c3) @ in # (d4 e5 f6) @ out # (g7 h8 i9

  1. )@in#( - это первый разделитель между двумя предыдущими подстроками (a1 b2 c3 и d4 e5 f6).
  2. )@out#( является необязательным разделителем для g7 h8 i9.
  3. Существует один или два пробела вокруг разделителя.

Интересно, что оба разделителя содержат несколько символов.

Я хочу использовать get все подстроки, используя Bash регулярное выражение . Это мой текущий код:

s1='a1 b2 c3 )@in#( d4 e5 f6 )@out#( g7 h8 i9'
s2='a1 b2 c3 )@in#( d4 e5 f6'

regex='^(.*)[[:space:]]+\)@in#\([[:space:]]+(.*)[[:space:]]+\)@out#\([[:space:]](.*)$'

[[ $s =~ $regex ]] && printf '%s\n%s\n%s\n%s\n' "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}

Код соответствует только s1, но не s2Вот почему я пишу этот пост для вашей помощи.

Кстати, кто-нибудь может немного уточнить разницу между [[:space:]] и \s.


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


Вместо того, чтобы просто печатать вывод,Я хочу записать их в переменные или read в массив для дальнейшего процесса.

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Мое окончательное решение заключается в следующем:

IFS=$'\n' _log_array=( $( awk -F'[[:space:]]*\\)@(in|out)#\\([[:space:]]*' '{ print NF; for (i = 1; i <= NF; ++i) print $i; }' <<< $s ) )
  1. Установите IFS на \n.
  2. Вместо печати на stdout , я назначаю вывод для массива .
  3. Обратите внимание на дополнительные скобки снаружи.

Вот две ссылки:

  1. https://stackoverflow.com/a/21130572/2336707
  2. https://stackoverflow.com/a/42635720/2336707
0 голосов
/ 17 января 2019

Вы можете попробовать Perl

$ echo "a1 b2 c3 )@in#( d4 e5 f6 )@out#( g7 h8 i9" | perl -lne ' @a=split(/\s*\)\@in#\(\s*|\s*\)\@out#\(\s*/); print join("\n",@a) '
a1 b2 c3
d4 e5 f6
g7 h8 i9

$ echo "a1 b2 c3 )@in#( d4 e5 f6 g7 h8 i9" | perl -lne ' @a=split(/\s*\)\@in#\(\s*|\s*\)\@out#\(\s*/); print join("\n",@a) '
a1 b2 c3
d4 e5 f6 g7 h8 i9

$

Вы можете прочитать вывод, пройдя через цикл while

$ echo "a1 b2 c3 )@in#( d4 e5 f6 g7 h8 i9" | perl -lne ' @a=split(/\s*\)\@in#\(\s*|\s*\)\@out#\(\s*/); print join("\n",@a) ' | while read x;do; echo "val=$x"; done
val=a1 b2 c3
val=d4 e5 f6 g7 h8 i9
$

или выведите каждое значение arr в perl и прочитайте их один за другим

$ echo "a1 b2 c3 )@in#( d4 e5 f6 g7 h8 i9" | perl -lne ' @a=split(/\s*\)\@in#\(\s*|\s*\)\@out#\(\s*/); print $a[0] ' | read x1
$ echo $x1
a1 b2 c3
$

$ echo "a1 b2 c3 )@in#( d4 e5 f6 g7 h8 i9" | perl -lne ' @a=split(/\s*\)\@in#\(\s*|\s*\)\@out#\(\s*/); print $a[1] ' | read x2
$ echo $x2
d4 e5 f6 g7 h8 i9
$
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...