grep corresponde exatamente a duas partes de uma string

grep corresponde exatamente a duas partes de uma string

Como uso o comando grep para obter parte da string conforme abaixo?

Corda:

orange:"orange", red:"apple", purple:"grape", yellow:"banana", green:"watermelon"
red:"strawberries", yellow:"lemon"

O que eu quero:

red:"apple" yellow:"banana"
red:"strawberries" yellow:"lemon"

Eu tentei isso:

grep -oP '(red:\"[^\"]*).*(yellow:\"[^\"]*)'

Responder1

O .*meio está combinando com tudo, ou seja, a purple:"grape"parte. Em vez disso (supondo que você queira continuar com o GNU grep), eu combinaria cada parte separadamente com a (foo|bar)construção "OR".

grep -oP '(red|yellow):\"[^\"]*"'

NB eu tive que adicionar o fechamento ". Além disso, você não precisa escapar do ", então você pode usar

grep -oP '(red|yellow):"[^"]*"'

Em qualquer caso, isso lhe dá

red:"apple"
yellow:"banana"

então, para unir as linhas com espaço entre elas,

grep -oP '(red|yellow):"[^"]*"' | paste -sd ' ' -

Honestamente, eu naturalmente usaria sed.

sed -n 's/.*\(red:"[^"]*"\).*\(yellow:"[^"]*"\).*/\1 \2/p'

Responder2

grepnormalmente não extrai conteúdo off-line. Ele pcopia as linhas que correspondem a uma expressão rregular ( lobalmente, é nomeado após o comando).egg/re/p ed

Algumas implementações como o GNU grep, que você parece estar usando, precisam -ofazer parte disso como uma extensão.

pcregrepvai ainda mais longe. Pode -oser necessário um argumento numérico opcional para gerar o conteúdo de um grupo de captura em oposição a toda a parte correspondente da linha.

pcregrep -o1 -o2 --om-separator=' ' '(red:"[^"]*").*(yellow:"[^"]*")'

Isso ainda é limitado no que pode fazer.

Para extrair informações da linha e fazer mais transformações, é um sfluxo de texto edque você deseja, como outros mostraram aqui.

Responder3

Você realmente pode fazer isso grepcomsugerido por Sparhawk, ou com o quase idêntico:

$  echo 'red:"apple", purple:"grape", yellow:"banana"' |      
        grep -oP '(red|yellow):".+?"' | perl -00pe 's/\n/ /'
red:"apple" yellow:"banana"

Pessoalmente, provavelmente faria isso com perl:

$ echo 'red:"apple", purple:"grape", yellow:"banana"' | 
    perl -F, -ane 'map{print if /red|yellow/}@F'
red:"apple" yellow:"banana"

informação relacionada