Может ли 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 выводить элементы, которые соответствуют группировке (или определенной группе) в регулярном выражении?

  • Копировать только Конкретный текст файла в другой
  • Как я могу найти и заменить только в том случае, если совпадение составляет целое слово?
  • Почему «while .. read .. << EOL» выполняет расширение переменной, но <файл и | не?
  • Как найти и заменить только определенное слово (которое находится в конце файла) с помощью команды оболочки?
  • egrep regular expression - одно и то же слово в начале и в конце
  • сценарий оболочки для извлечения символов
  • найти и заменить строку в файле без использования временного файла с SED
  • Греп для числа в строке
  • 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

    Ввод в терминал подчеркивает символы, добавляет символы с акцентом

    «Ls -b» не работает на macOS

    возможно ли создать файл с учетом хеша md5

    «Установка файловой системы ext3 с использованием подсистемы ext4» – что это значит?

    Сделать ядро: не удалось создать рецепт для цели

    Название всей программы не отображается в nethogs

    Отключить зависимости от сбоя обновления zypper

    Есть ли способ добавить каталог в мой PATH в zsh, только если он еще не присутствует?

    Корневая файловая система NFS не монтируется при загрузке

    scons не может найти glib-2.0> = 2.32 на cygwin

    Информация о сокетах и ​​ядрах. Как проверить пустые сокеты?

    Использование поиска для поиска и отправки отчетов, содержащих один, но не два ключевых слова внутри

    Xmove не может подключиться к серверу X11 через пересылку SSH X

    Установка (полу-?) Перебалансированного привода btrfs

    Редактор Linux с режимом направления VMS EDT

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