grep
Имя идет после g / re / p
ed
команда. Его основная цель - напечатать строки, соответствующие регулярному выражению. Редактировать содержимое этих строк не его роль. Для этого у вас есть sed
(редактор потока) или awk
.
Теперь в некоторых реализациях grep
, начиная с GNU grep
, добавлен параметр -o
для печати совпадающей части каждой строки (что соответствует regexp, а не его группы захвата). У вас есть реализация grep
, подобная GNU (с -P
) или pcregrep
, которые поддерживают PCRE для своих регулярных выражений.
pcregrep
фактически добавил параметр -o
для печати содержимого группы захвата.Итак, вы можете сделать:
pcregrep -o1 -o2 --om-separator=' ' '.zoo.(\d+).*:\s+(.*)'
Но здесь очевидное стандартное решение - использовать sed
:
sed -n 's/^.*\.zoo\.\([0-9]\{1,\}\).*:[[:space:]]\{1,\}/\1 /p'
Или, если вам нужны регулярные выражения Perl, используйте perl:
perl -lne 'print "$1 $2" if /\.zoo\.(\d+).*:\s+(.*)/'
С GNU grep
, если вы не против, чтобы совпадения отображались в разных строках, вы можете сделать:
$ grep -Po '\.zoo\.\K\d+|:\s+\K.*' < file
2
0.45654343
Обратите внимание, что хотя \ K
сбрасывает начало совпадающей части, это не означает, что вы можете получить прочь с перекрытием двух частей чередования.
grep -Po '.zoo. (\ K \ d + |. : \ K. )'
не будет работать, как и echo foobar | grep -Po 'foo | foob'
не будет работать (при печати как foo
, так и foob
). foo | foob
сначала соответствует foo
, а затем grep
ищет возможные другие совпадения во входных данных после foo
, поэтому, начиная с b
из бара
, поэтому больше ничего не могу найти.
Выше с grep -Po '\ .zoo \. \ K \ d + |: \ s + \ K. *'
, мы ищем только : <пробелы> <что-нибудь>
во второй части чередования. Это соответствует части, которая находится после .zoo.
, но это также означает, что он найдет эти :
где угодно во входных данных, а не только когда они следуют за .zoo. <цифры>
.
Однако есть способ обойти это, используя другой специальный оператор PCRE: \ G
. \ G
соответствует началу темы.Для одного совпадения это эквивалентно ^
, но с несколькими совпадениями (подумайте о sed
/ perl
флаге g
в s /.../.../ g
) как с -o
, где grep
пытается найти все совпадения в строке, которая также совпадает после конец предыдущего матча. Итак, если вы сделаете это:
grep -Po '\.zoo\.\K\d+|(?!^)\G.*:\s+\K.*'
Где (?! ^)
- оператор отрицательного просмотра вперед, что означает не в начале строки , что \ G
будет соответствовать только после предыдущего успешного (непустого) совпадения, поэтому . *: \ S + \ K. *
будет соответствовать, только если он следует за предыдущим успешным совпадением, и это может быть только .foo.
один, поскольку другая часть чередования совпадает до конца строки.
На входе вроде:
.zoo.1.zoo.2 tar: blah
Что бы вывести:
1
2
blah
Хотя. Если вы этого не хотите, вы бы также хотели, чтобы первая часть чередования совпадала только с началом строки. Что-то вроде
grep -Po '^.*?\.zoo\.\K\d+|(?!^)\G.*:\s+\K.*'
Это все еще выводит 2
на входе типа .zoo.2 без символа двоеточия
или .zoo.2 blah:
. Вы можете обойти это с помощью оператора упреждающего просмотра в первой части чередования и найти хотя бы один непробел после :
(а также с помощью $
чтобы избежать проблем с не-символами)
grep -Po '^.*?\.zoo\.\K\d+(?=.*:\s+\S.*$)|(?!^)\G.*:\s+\K\S.*$'
Вам, вероятно, понадобится несколько страниц комментариев, чтобы объяснить это регулярное выражение, поэтому я бы все равно выбрал прямые sed
/ perl
решения ...
См. инструкции по установке для пакетов Debian на CRAN, раздел Secure apt:
Архивы бэкпортов Debian на CRAN подписаны ключом Йоханнес Ранке (архив CRAN Debian) с ключом отпечаток пальца 6212 B7B7 931C 4BB1 6280 BA13 06F9 0DE5 381B A480. Ты может получить и импортировать это с
apt-key adv --keyserver keys.gnupg.net --recv-key 6212B7B7931C4BB16280BA1306F90DE5381BA480