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
grep
normalmente não extrai conteúdo off-line. Ele p
copia as linhas que correspondem a uma expressão r
regular ( lobalmente, é nomeado após o comando).e
g
g/re/p
ed
Algumas implementações como o GNU grep
, que você parece estar usando, precisam -o
fazer parte disso como uma extensão.
pcregrep
vai ainda mais longe. Pode -o
ser 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 s
fluxo de texto ed
que você deseja, como outros mostraram aqui.
Responder3
Você realmente pode fazer isso grep
comsugerido 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"