Используйте grep для извлечения текста из файла на основе регулярного выражения

Используйте grep для извлечения текста из файла на основе регулярного выражения

У меня есть этот файл:

header:
  title: hello
  version: 1.2.3

Я хочу извлечь номер версии.

Моя первоначальная попытка была

grep ^\s+version:\s+(\d\.\d\.\d) file.txt

но это дало пустой вывод. После предложений в комментариях я попробовал

grep -P '^\s+version:\s+(\d\.\d\.\d)' file.txt

но я получаю "версия: 1.2.3" вместо "1.2.3".

Что я делаю не так?

решение1

grepиспользуетБазовое регулярное выражение Posix( BRE) по умолчанию, что не поддерживает вашу нотацию.

Используйте grep -Eдля использования Posix Extended Regex ( ERE) и grep -Pдля использования Perl Compatible Regex ( PCRE), если они доступны.

Ваша нотация работает с grep -P:

grep -P '^\s+version:\s+(\d\.\d\.\d)' file.txt

Это работает с BRE:

grep '^ \+version: \+\([0-9]\.[0-9]\.[0-9]\)' file.txt

Выход:

  version: 1.2.3

Обратите внимание, что группа захвата здесь не нужна, так как grepона ничего не делает.


Если вам нужна только версия №,использовать\Kи -oвариант:

grep -Po '^\s+version:\s+\K\d\.\d\.\d' file.txt

Выход:

1.2.3

С BRE, это невозможно, вам придется объединить две grepкоманды:

grep 'version: ' file.txt | grep -o '[0-9]\.[0-9]\.[0-9]'

или используйте sed(кредит @Kusalananda):

sed -n 's/.*version: //p' file.txt

решение2

Согласно комментариюpLumoиКак использовать grep, чтобы получить что-либо сразу после именирабочая команда может быть

 grep -oP "(?<=version: )(\d\.\d\.\d)" file.txt

Связанный контент