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

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

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

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

 "foobar \(\w\+\)" 

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

 foobar bash 1 foobar happy 

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

 bash happy 

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

  • Есть ли надежный инструмент командной строки для обработки CSV-файлов?
  • замените с начала строки на 1 из нескольких шаблонов в конец другой строки со вторым шаблоном
  • Получить строку запроса из URL-адресов в файле журнала
  • Как заменить начальный ноль пробелом в SED?
  • Проблема удаления / замены специального символа °
  • Как найти текст, скопировать его и вставить в следующую строку в файле?
  • Как сделать просмотрщик PDF восприимчивым к изменениям в Debian
  • Разделите базовое имя файла, сохраните часть каталога
  • 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 основан на нуле.

    Interesting Posts

    Xfce 4: как сменить быстрые клавиши на глобальном уровне (для всех учетных записей пользователей)?

    Как синхронизировать несколько устройств Palm PDA?

    XMLstarlet для JSON?

    Можно ли использовать коды escape-кода ANSI в Bash здесь-документах?

    Как запустить PC-BSD iso из GRUB только с установленным Linux

    Мой Linux-рабочий стол зависает случайно. Что искать в журналах

    Если имя папки равно «somestring», переместите все файлы в папке на один уровень вверх

    netcat из-за NAT

    Как сделать полный набор возможностей для определения «командных символов» на GNU?

    Как настроить isc-dhcp-сервер, чтобы предлагать серверы upstream DNS?

    Редактирование внешнего объема Truecrypt Hidden Volume?

    Как программное обеспечение скомпилировано и перенесено на Ubuntu?

    Напишите удаленный управляющий скрипт

    что такое awk '{print $ 1 + 0.45 "" $ 2 "" $ 3}' file1> file2?

    Как открыть tty или выполнить какой-либо скрипт, когда ярлык Ctrl + Alt + F не работает, а X11 частично заморожен, но система все еще работает?

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