grep соответствует всем вхождениям нескольких регулярных выражений

Я нашел причину проблемы. Медленное соединение было из-за конфигурации IPv6. Когда я отключил IPv6, все заработало нормально.

$ sudo nano /etc/sysctl.conf

Добавлены следующие конфигурации в конец файла:

# IPv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

Затем перезапущен sysctl.conf:

$ sudo sysctl -p
0
04.09.2017, 18:02
2 ответа

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

grep -o '|| *[^ ]*' file
grep -o '[^ ]* *||' file

Или объедините с awk:

grep -o '[^ ]* *|| *[^ ]*' file | awk -F' *\\|\\| *' '{ print $1; print $2 }'

Given строка примера

select * from table where :first-var || :second-var

, которая будет производить

:first-var
:second-var
0
28.01.2020, 02:19

Проблема в том, что после нахождения :first-var ||в оставшемся тексте не осталось || :second-var. grep -oможет печатать только те части строк, которые не перекрываются.

Вы могли бы сделать:

$ perl -lne 'print for /:\S+\s+\|\|/g, /\|\|\s+:\S+/g' file
:first-var ||
|| :second-var

(со всеми :var ||напечатанными перед || :varс ).

Или, если вам нужна только часть :var, с GNU grepс поддержкой PCRE:

$ grep -Po ':\S+(?=\s+\|\|)|\|\|\s+\K:\S+' file
:first-var
:second-var

То же, что и:

perl -lne 'print for /:\S+(?=\s+\|\|)|\|\|\s+\K:\S+/g'

Теперь, если вы хотите извлечь :fooи :barв строку, которая всегда имеет форму anything :foo || :bar, вы можете сделать это стандартно с помощью:

s='[[:space:]]\{1,\}' S='[^[:space:]]\{1,\}'
sed -n "/\(:$S\}\)$s\{1,\}||$s\(:$S\).*/{
  s//\
\1\
\2/
  s/.*\n\(.*\n\)/\1/p
}'
3
28.01.2020, 02:19

Теги

Похожие вопросы