Комплексное регулярное выражение - работает в Powershell, а не в Bash - PullRequest
0 голосов
/ 28 ноября 2018

Приведенный ниже код представляет собой небольшую часть моего кода для Solarwinds для анализа вывода команды Netbackup.Это хорошо для наших коробок Windows, но некоторые из наших коробок RHEL.

Я пытаюсь преобразовать приведенный ниже код во что-то пригодное для использования в RHEL 4.X, но я вхожу в стену с разбором регулярных выражений.Очевидно, что в приведенном ниже коде некоторые символы экранированы для использования с Powershell, я удалил эти символы для использования с Shell.

У меня пока не все в порядке с Shell, но я опубликую часть кода Shell ниже кода Powershell.

$output = ./bpdbjobs

$Results = @()
$ColumnName = @()

foreach ($match in $OUTPUT) {
   $matches = $null
   $match -match "(?<jobID>\d+)?\s+(?<Type>(\b[^\d\W]+\b)|(\b[^\d\W]+\b\s+\b[^\d\W]+\b))?\s+(?<State>(Done)|(Active)|(\w+`-\w+`-\w+))?\s+(?<Status>\d+)?\s+(?<Policy>(\w+)|(\w+`_\w+)|(\w+`_\w+`_\w+))?\s+(?<Schedule>(\b[^\d\W]+\b\-\b[^\d\W]+\b)|(\-)|(\b[^\d\W]+\b))?\s+(?<Client>(\w+\.\w+\.\w+)|(\w+))?\s+(?<Dest_Media_Svr>(\w+\.\w+\.\w+)|(\w+))?\s+(?<Active_PID>\d+)?\s+(?<FATPipe>\b[^\d\W]+\b)?"
   $Results+=$matches
   }

Ниже приведена небольшая часть написанного мною кода Shell (который явно очень неправильный, изучая, как я здесь иду).Я просто использую это, чтобы проверить Regex и посмотреть, работает ли он в Shell - (Оповещение о спойлере) нет.

#!/bin/bash
#

backups=bpdbjobs
results=()

for results in $backups; do

    [[ $results =~ /(?<jobID>\d+)?\s+(?<Type>(\b[^\d\W]+\b)|(\b[^\d\W]+\b\s+\b[^\d\W]+\b))?\s+(?<State>(Done)|(Active)|(\w+\w+\-\w\-+))?\s+(?<Status>\d+)?\s+(?<Policy>(\w+)|(\w+\_\w+)|(\w+\_\w+\_\w+))?\s+(?<Schedule>(\b[^\d\W]+\b\-\b[^\d\W]+\b)|(\-)|(\b[^\d\W]+\b))?\s+(?<Client>(\w+\.\w+\.\w+)|(\w+))?\s+(?<Dest_Media_Svr>(\w+\.\w+\.\w+)|(\w+))?\s+(?<Active_PID>\d+)?/ ]]

done

$results

Ниже приведены ошибки, которые я получаю.

 ./netbackupsolarwinds.sh: line 9: syntax error in conditional expression: unexpected token `('
 ./netbackupsolarwinds.sh: line 9: syntax error near `/(?'
 ./netbackupsolarwinds.sh: line 9: `        [[ $results =~ /(?<jobID>\d+)?\s+(?<Type>(\b[^\d\W]+\b)|(\b[^\d\W]+\b\s+\b[^\d\W]+\b))?\s+(?<State>(Done)|(Active)|(\w+\w+\-\w\-+))?\s+(?<Status>\d+)?\s+(?<Policy>(\w+)|(\w+\_\w+)|(\w+\_\w+\_\w+))?\s+(?<Schedule>(\b[^\d\W]+\b\-\b[^\d\W]+\b)|(\-)|(\b[^\d\W]+\b))?\s+(?<Client>(\w+\.\w+\.\w+)|(\w+))?\s+(?<Dest_Media_Svr>(\w+\.\w+\.\w+)|(\w+))?\s+(?<Active_PID>\d+)?/ ]]'

Ответы [ 3 ]

0 голосов
/ 28 ноября 2018

С man bash:

Доступен дополнительный двоичный оператор = ~, имеющий тот же приоритет, что и == и! =.Когда это используется, строка справа от оператора считается расширенным регулярным выражением и соответствует соответствующим образом (как в regex (3)).

Это означает, что выражениеанализируется как расширенное регулярное выражение POSIX, которое AFAIK не поддерживает ни именованными группами захвата ((?<name>...)), ни символами (\d, \w, \s, ...).

Если вы хотите использовать [[ $var =~ expr ]], вам нужно переписать регулярное выражение.В противном случае используйте grep (который поддерживает PCRE):

grep -P '(?<jobID>\d+)?\s+...' <<<$results
0 голосов
/ 29 ноября 2018

Спасибо всем за ответы.Я переключился на Grep -P безрезультатно, оказалось, что названные группы захвата были проблемой для Grep -P.

Мне также не удалось найти способ использовать Grep для вывода совпадений группы захвата для отдельныхПеременные.

Это привело меня к использованию perl следующим образом с изменениями в моем регулярном выражении.

bpdbjobs | perl -lne 'print "$1" if /(\d+)?\s+((\b[^\d\W]+\b)|(\b[^\d\W]+\b\s+\b[^\d\W]+\b))?\s+((Done)|(Active)|(\w+\w+\-\w\-+))?\s+(\d+)?\s+((\w+)|(\w+\_\w+)|(\w+\_\w+\_\w+))?\s+((b[^\d\W]+\b\-\b[^\d\W]+\b)|(\-)|(\b[^\d\W]+\b))?\s+((\w+\.\w+\.\w+)|(\w+))?\s+((\w+\.\w+\.\w+)|(\w+))?\s+(\d+)?/g'

С $<num>, относящимся к захватуномер группы.Теперь я могу перечислить, отобразить и (важная часть) подсчитать количество совпадений в отдельной группе, соответствующее данным, найденным в каждом столбце.

0 голосов
/ 28 ноября 2018

Обновленный ответ после обмена комментариями.

Лучший способ быстро выполнить миграцию - использовать параметр совместимости Perl --perl-regexp в Grep, как в конечном итоге было предложено в другом ответе.

Если вы все еще хотите выполнить эту операцию с использованием чистого Bash, вам необходимо соответствующим образом переписать регулярное выражение, следуя документации .

...