Может ли grep выводить только указанные группы, которые соответствуют?

Скажем, у меня есть файл:

# file: 'test.txt' foobar bash 1 bash foobar happy foobar 

Я только хочу знать, какие слова появляются после «foobar», поэтому я могу использовать это регулярное выражение:

  • Как совместить строку, содержащую символ «$» с grep?
  • Найти файлы, начинающиеся с ~ $ (MicroSoft Word Temp файлы)
  • Конкретная замена уровня столбца
  • Извлечь строки, которые имеют конкретное окончание, и использовать их для извлечения из другого файла
  • Добавить строку суффикса в конец каждой строки?
  • Строки Grep, где изменения происходят в столбцах
  •  "foobar \(\w\+\)" 

    Скобки указывают, что у меня есть особый интерес к слову сразу после foobar. Но когда я делаю grep "foobar \(\w\+\)" test.txt , я получаю все строки, которые соответствуют всему регулярному выражению, а не просто «слово после foobar»:

     foobar bash 1 foobar happy 

    Я бы предпочел, чтобы результат этой команды выглядел так:

     bash happy 

    Есть ли способ сообщить grep выводить элементы, которые соответствуют группировке (или определенной группе) в регулярном выражении?

  • Найти рекурсивный поиск Grep
  • Подстановка первого вхождения шаблона в строку, для всех строк в файле с sed
  • Есть ли файл конфигурации «rc» для grep / egrep? (~ / .egreprc?)
  • Сломанная труба при выходе grepping, но только с флагом -i
  • Удалить комментарии в файле C
  • найти команду с помощью квантификатора regex, например {1,2}
  • 5 Solutions collect form web for “Может ли grep выводить только указанные группы, которые соответствуют?”

    GNU grep имеет параметр -P для регулярных выражений в стиле perl, а параметр -o печатает только то, что соответствует шаблону. Их можно объединить, используя утверждения обхода (описанные в разделе Расширенные шаблоны в man-странице perlre ), чтобы удалить часть шаблона grep из того, что определено для соответствия для целей -o .

     $ grep -oP 'foobar \K\w+' test.txt bash happy $ 

    \K – это короткая форма (и более эффективная форма) (?<=pattern) которую вы используете как выражение с обратной связью с нулевой шириной перед текстом, который вы хотите вывести. (?=pattern) можно использовать в качестве подтверждения с нулевой шириной после текста, который вы хотите вывести.

    Например, если вы хотите совместить слово между foo и bar , вы можете использовать:

     $ grep -oP 'foo \K\w+(?= bar)' test.txt 

    или (для симметрии)

     $ grep -oP '(?<=foo )\w+(?= bar)' test.txt 

    Стандартный grep не может этого сделать, но последние версии GNU grep могут . Вы можете обратиться к sed, awk или perl. Вот несколько примеров, которые делают то, что вы хотите на своем примере ввода; они ведут себя немного по-разному в угловых случаях.

    Замените foobar word other stuff word , напечатайте, только если замена выполнена.

     sed -n -e 's/^foobar \([[:alnum:]]\+\).*/\1/p' 

    Если первое слово является foobar , напечатайте второе слово.

     awk '$1 == "foobar" {print $2}' 

    Полоса foobar если это первое слово, и пропустите линию иначе; затем разделите все после первого пробела и распечатайте.

     perl -lne 's/^foobar\s+// or next; s/\s.*//; print' 

    Ну, если вы знаете, что foobar всегда является первым словом или линией, вы можете использовать разрез. Вот так:

     grep "foobar" test.file | cut -d" " -f2 
      sed -n "s/^.*foobar\s*\(\S*\).*$/\1/p" -n suppress printing s substitute ^.* anything before foobar foobar initial search match \s* any white space character (space) \( start capture group \S* capture any non-white space character (word) \) end capture group .*$ anything after the capture group \1 substitute everything with the 1st capture group p print it 

    Если PCRE не поддерживается, вы можете добиться того же результата с помощью двух вызовов grep. Например, чтобы захватить слово после foobar, выполните следующее:

     <test.txt grep -o 'foobar *[^ ]*' | grep -o '[^ ]*$' 

    Это можно развернуть до произвольного слова после foobar, как это (с ERE для удобочитаемости):

     i=1 <test.txt egrep -o 'foobar +([^ ]+ +){'$i'}[^ ]+' | grep -o '[^ ]*$' 

    Вывод:

     1 

    Обратите внимание, что индекс i основан на нуле.

    Linux и Unix - лучшая ОС в мире.