Парсинг и фильтрация строк в bash по регулярным выражениям
Примеры парсинга и фильтрации строк в bash - grep, =~ (BASH_REMATCH).
Trim
echo ' string wirh spaces ' | tr -d ' '
Разделение строки
Разбить строки по заданному разделителю:
echo "1;2;3" | tr ";" "\n"
Разделить строку и получить 2ю часть:
str='one;two;three'
echo $str | cut -d ';' -f2 # two
my_var="$( cut -d ';' -f 2 <<< "$str" )";
Извлечь первую строку (first line):
cat file | head -n 1
Позитивные и негативные проверки
Подробнее: http://bit.ly/1sBvdoD
(?<=) Позитивная ретроспективная проверка (positive lookbehind assertion) !Доступна только в PCRE режиме. Продолжает поиск только если слева от текущей позиции в тексте находится заключённое в скобки выражение
(?=) Положительная опережающая проверка (positive lookahead assertion). Продолжает поиск только если справа от текущей позиции в тексте находится заключённое в скобки выражение.
(?<!) Негативная ретроспективная проверка (negative lookbehind assertion). Продолжает поиск только если слева от текущей позиции в тексте не находится заключённое в скобки выражение.
(?!) Негативная опережающая проверка (negative lookahead assertion). Продолжает поиск только если справа от текущей позиции в тексте не находится заключённое в скобки выражение.
Пример использования утилитой grep:
echo 'text<b>bold</b> end, not bold' | grep -Poi '(?<=text<b>).+(?=\<)' ## bold
Поиск и фильтрация строк
GREP
Помните!
Любой grep'подобный regex поиск не позволяет захватывать (capture) группу вхождений подобно $BASH_REMATCH в операторе сравнения =~
.
Найти текст по маске regex:
echo 'text<b>bold</b> end, not bold' | grep -Poi '(?<=text<b>).+(?=\<)' ## bold
ifconfig ppp0 | grep -Po 'P-t-P:\K([\d\.]+)' ## 10.64.64.64
-i регистро-независимый поиск
-o выводить не всю строку, а лишь найденный шаблон
-P --perl-regexp, шаблон как Perl совместимое регулярное выражение
-E --extended-regexp, шаблон как расширенное регулярное выражение (ERE)
\K захватывать только выражение в (скобках)
BASH_REMATCH
Разобрать строку на части по regex шаблону:
if [[ "$line" =~ ^\ ?(--platform) ]]; then
# Установить $match, если $BASH_REMATCH пустой
if [[ $BASH_REMATCH != '' ]]; then
match=("${BASH_REMATCH[@]}")
fi
echo $line
printf -- '%s\n' "${arr[@]}" ## Или: echo ${match[@]}
echo ${match[1]}
fi
Примечание
В zsh вместо переменной с вхождениями BASH_REMATCH доступен массив $match. В примере ниже я устанавливаю в $match одну из доступных переменных.
Поиск в нескольких строках:
... | pcregrep -iM '<annot.*?>(.|\n)+?</annot'
#regex, #grep, #awk