Как использовать команду grep, чтобы получить часть строки, как показано ниже?
Нить:
orange:"orange", red:"apple", purple:"grape", yellow:"banana", green:"watermelon"
red:"strawberries", yellow:"lemon"
Что я хочу:
red:"apple" yellow:"banana"
red:"strawberries" yellow:"lemon"
Я попробовал это:
grep -oP '(red:\"[^\"]*).*(yellow:\"[^\"]*)'
решение1
В .*
середине соответствует всему, т.е. purple:"grape"
части. Вместо этого (предполагая, что вы хотите придерживаться GNU grep), я бы сопоставил каждую часть отдельно с помощью (foo|bar)
конструкции "ИЛИ".
grep -oP '(red|yellow):\"[^\"]*"'
NB Мне пришлось добавить закрывающую "
. Кроме того, вам не нужно экранировать "
, поэтому вы можете использовать
grep -oP '(red|yellow):"[^"]*"'
В любом случае, это дает вам
red:"apple"
yellow:"banana"
затем соединить строки с пробелом между ними,
grep -oP '(red|yellow):"[^"]*"' | paste -sd ' ' -
Честно говоря, я бы, естественно, использовал sed
.
sed -n 's/.*\(red:"[^"]*"\).*\(yellow:"[^"]*"\).*/\1 \2/p'
решение2
grep
обычно не извлекает содержимое из строк. Он p
выводит строки, соответствующие r
регулярному e
выражению ( g
глобально он назван в честь g/re/p
ed
команды).
Однако некоторые реализации, такие как GNU grep
, которую вы, судя по всему, используете, имеют возможность -o
делать что-то из этого в виде расширения.
pcregrep
идет еще дальше. Он -o
может принимать необязательный числовой аргумент для вывода содержимого группы захвата, а не всей совпавшей части строки.
pcregrep -o1 -o2 --om-separator=' ' '(red:"[^"]*").*(yellow:"[^"]*")'
Его возможности по-прежнему ограничены.
Чтобы извлечь информацию из строки и выполнить дополнительные преобразования, вам понадобится текстовый s
процессор , как уже было показано здесь.ed
решение3
Вы действительно можете сделать это с grep
помощьюпредложено Спархоком, или с почти идентичным:
$ echo 'red:"apple", purple:"grape", yellow:"banana"' |
grep -oP '(red|yellow):".+?"' | perl -00pe 's/\n/ /'
red:"apple" yellow:"banana"
Лично я бы, наверное, сделал это с помощью perl
:
$ echo 'red:"apple", purple:"grape", yellow:"banana"' |
perl -F, -ane 'map{print if /red|yellow/}@F'
red:"apple" yellow:"banana"