¿Cómo uso el comando grep para obtener parte de la cadena como se muestra a continuación?
Cadena:
orange:"orange", red:"apple", purple:"grape", yellow:"banana", green:"watermelon"
red:"strawberries", yellow:"lemon"
Lo que quiero:
red:"apple" yellow:"banana"
red:"strawberries" yellow:"lemon"
He probado esto:
grep -oP '(red:\"[^\"]*).*(yellow:\"[^\"]*)'
Respuesta1
El .*
del medio coincide con todo, es decir, con la purple:"grape"
pieza. En cambio (suponiendo que quieras seguir con GNU grep), combinaría cada parte por separado con la (foo|bar)
construcción "OR".
grep -oP '(red|yellow):\"[^\"]*"'
NB, tuve que agregar el cierre "
. Además, no es necesario escapar de "
, por lo que puedes usar
grep -oP '(red|yellow):"[^"]*"'
En cualquier caso, esto te da
red:"apple"
yellow:"banana"
luego unir las líneas con espacio entre ellas,
grep -oP '(red|yellow):"[^"]*"' | paste -sd ' ' -
Honestamente, naturalmente lo usaría sed
en su lugar.
sed -n 's/.*\(red:"[^"]*"\).*\(yellow:"[^"]*"\).*/\1 \2/p'
Respuesta2
grep
Normalmente no extrae contenido fuera de línea. Imprime p
las líneas que coinciden con una expresión r
regular e
( g
lobalmente, lleva el nombre del g/re/p
ed
comando).
Sin embargo, algunas implementaciones como GNU grep
que parece que estás usando tienen que -o
hacer algo de eso como una extensión.
pcregrep
va aún más lejos. Puede -o
tomar un argumento numérico opcional para generar el contenido de un grupo de captura en lugar de toda la parte coincidente de la línea.
pcregrep -o1 -o2 --om-separator=' ' '(red:"[^"]*").*(yellow:"[^"]*")'
Eso todavía es limitado en lo que puede hacer.
Para extraer información de la línea y realizar más transformaciones, es mejor utilizar un s
procesador de texto como lo han mostrado otros aquí.ed
Respuesta3
De hecho puedes hacerlo con grep
comosugerido por Sparhawk, o con el casi idéntico:
$ echo 'red:"apple", purple:"grape", yellow:"banana"' |
grep -oP '(red|yellow):".+?"' | perl -00pe 's/\n/ /'
red:"apple" yellow:"banana"
Personalmente, probablemente lo haría con perl
:
$ echo 'red:"apple", purple:"grape", yellow:"banana"' |
perl -F, -ane 'map{print if /red|yellow/}@F'
red:"apple" yellow:"banana"