Вопрос по linux, grep – Как найти содержимое после шаблона?

59

Для данного файла, например:

<code>potato: 1234
apple: 5678
potato: 5432
grape: 4567
banana: 5432
sushi: 56789
</code>

Я хотел бы использовать grep для всех строк, начинающихся сpotato: но только труба цифры, которые следуютpotato:, Таким образом, в приведенном выше примере, результат будет:

<code>1234
5432
</code>

Как я могу это сделать?

Ваш Ответ

5   ответов
2

Это напечатает все после каждого совпадения, только в той же строке:

perl -lne 'print $1 if /^potato:\s*(.*)/' file.txt

Это сделает то же самое, за исключением того, что он также напечатает все последующие строки:

perl -lne 'if ($found){print} elsif (/^potato:\s*(.*)/){print $1; $found++}' file.txt

Эти параметры командной строки используются:

  • -n loop around each line of the input file
  • -l removes newlines before processing, and adds them back in afterwards
  • -e execute the perl code
1

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

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

$ while read line;
  do
    if [[ "${line%%:\ *}" == "potato" ]];
    then
      echo ${line##*:\ };
    fi;
  done< file.txt

## говорит bash удалить самое длинное совпадение & quot ;: & quot; в $ линию с фронта.

$ while read line; do echo ${line##*:\ }; done< file.txt
1234
5678
5432
4567
5432
56789

или, если вы хотите получить ключ, а не значение, %% говорит bash удалить самое длинное совпадение & quot ;: & quot; в $ строке от конца.

$ while read line; do echo ${line%%:\ *}; done< file.txt
potato
apple
potato
grape
banana
sushi

Подстрока, на которую нужно разделить - это & quot; \ \ quot; потому что символ пробела должен быть экранирован с помощью обратной косой черты.

Вы можете найти больше таких как напроект документации linux.

76
grep 'potato:' file.txt | sed 's/^.*: //'

или же

grep 'potato:' file.txt | cut -d\   -f2

или же

grep 'potato:' file.txt | awk '{print $2}'

или же

grep 'potato:' file.txt | perl -e 'for(<>){s/^.*: //;print}'

или же

awk '{if(/potato:/) print $2}' < file.txt

или же

perl -e 'for(<>){/potato:/ && s/^.*: // && print}' < file.txt
Скрипты Perl могут извлечь выгоду изperl -pe
Хорошее использованиеcut! (У нас сегодня работает легкий вес. Я должен вам +1 после обновления 00:00 UTC.)
Awk один будет более идиоматическиawk '/potato:/ {print $2}'
Нет необходимости в двух процессах и трубе. Я бы пошел наawk '$1 ~ /potato/ { print $2 }' file.txt.
эти варианты требуют пояснения
7
sed -n 's/^potato:[[:space:]]*//p' file.txt

Можно рассматривать Grep как ограниченный Sed или Sed как обобщенный Grep. В этом случае Sed - это один хороший и легкий инструмент, который делает то, что вы хотите - хотя, конечно, есть и несколько других разумных способов сделать это.

+1 хорошее использованиеsed!
48

Или используйте регулярные выражения:grep -oP '(?<=potato: ).*' file.txt

Я попробовал некоторые строки из принятого ответа выше, но я чувствую, что этот ответ более точно решает вопрос.
+1 приятно, не знал об этом!
Некоторое объяснение: вариант-o означает печатать только соответствующую часть строки. В то время как-P выводит Perl-совместимое регулярное выражение, которое оказываетсяpositive lookbehind регулярное выражение(?<=string).

Похожие вопросы