grep - exakte Übereinstimmung zweier Teile einer Zeichenfolge

grep - exakte Übereinstimmung zweier Teile einer Zeichenfolge

Wie verwende ich den Grep-Befehl, um einen Teil der Zeichenfolge wie unten zu erhalten?

Zeichenfolge:

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

Was ich möchte:

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

Ich habe Folgendes versucht:

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

Antwort1

Das .*in der Mitte passt alles an, also den purple:"grape"Teil. Stattdessen (vorausgesetzt, Sie möchten bei GNU grep bleiben) würde ich jeden Teil einzeln mit der (foo|bar)„ODER“-Konstruktion abgleichen.

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

NB: Ich musste das schließende hinzufügen ". Außerdem müssen Sie das nicht maskieren ", Sie können also verwenden

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

Auf jeden Fall gibt Ihnen das

red:"apple"
yellow:"banana"

dann die Zeilen mit Abstand dazwischen zu verbinden,

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

Ehrlich gesagt würde ich sedstattdessen natürlich verwenden.

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

Antwort2

grepextrahiert normalerweise keinen Inhalt aus den Zeilen. Es pdruckt die Zeilen aus, die einem rregulären eAusdruck entsprechen ( ges ist allgemein nach dem g/re/p edBefehl benannt).

Einige Implementierungen wie GNU grep, das Sie anscheinend verwenden, können -oeinige dieser Funktionen jedoch als Erweiterung ausführen.

pcregrepgeht sogar noch weiter. Es -okann ein optionales numerisches Argument annehmen, um den Inhalt einer Erfassungsgruppe auszugeben, anstatt des gesamten übereinstimmenden Teils der Zeile.

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

Die Möglichkeiten sind immer noch begrenzt.

Um Informationen aus der Zeile zu extrahieren und weitere Transformationen durchzuführen, benötigen Sie stattdessen einen Texttream s- edItor, wie andere hier gezeigt haben.

Antwort3

Sie können es tatsächlich mit grepso tunvorgeschlagen von Sparhawk, oder mit dem fast identischen:

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

Persönlich würde ich es wahrscheinlich so machen perl:

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

verwandte Informationen