Wie gibt man nur eine Spalte aus, die konstante Nachbarn hat?

Wie gibt man nur eine Spalte aus, die konstante Nachbarn hat?

EINGANG

AA XXX Y1Y ZZZ GG dhz
rr (AAAa) XXX Y2Y ZZZ TT GGGG UU

AUSGABE

Y1Y
Y2Y

Die Eingabezeilen können variieren. Nur XXX vor Y1Y und ZZZ nach Y1Y sind konstant (sie sind so die Nachbarn von XXX und ZZZ). Y1Y kann alles sein, z. B.: Y1Y, Y2Y, Y1T usw.

Q:wie kann ich die AUSGABE mit awk oder sed oder grep erhalten? (oder gibt es dafür bessere Tools?)

AKTUALISIEREN(Problem): Warum funktioniert es nicht, wenn im Y1Y ein „.“ steht?

[user@notebook ~] echo 'XXX Y1Y ZZZ' | grep -Po "(?<=XXX )(\w+)(?= ZZZ)"
Y1Y
[user@notebook ~] echo 'XXX Y1.Y ZZZ' | grep -Po "(?<=XXX )(\w+)(?= ZZZ)"
[user@notebook ~] 

Antwort1

Sie können grephierfür die bereitgestellte PCRE-Funktion verwenden:

$ grep -Po "(?<=XXX )\S+(?= ZZZ)" data.txt 
Y1Y
Y2Y

Einzelheiten

Diese Lösung nutzt die Lookbehind- und Lookahead-Funktion von PCRE, die Zeichenfolgen mit fester Länge abgleichen kann.

Oben wird hinter jedem nachgeschaut, \w+ob es ist, XXXund vor jedem, \w+um zu sehen, ob es ist ZZZ. Wenn ja, dann ist es eine Übereinstimmung. Der -oSchalter auf grepweist an, nur die Übereinstimmungen zu drucken, d. h \w+. .

Folgefrage: Können Sie es mit sed machen?

Ich glaube nicht, dass sich dieses Problem mit lösen lässt sed. Meiner Ansicht nach gibt es zwei Ansätze.

  1. Speichern Sie mögliche Übereinstimmungen in einer Nebenvariable. Wenn Sie auf ZZZ stoßen, drucken Sie sie aus.
  2. s/XXX ..unsere Zeichenfolge.. ZZZ/ ..unsere Zeichenfolge../

Nr. 1 scheint ziemlich viel Arbeit zu sein, deshalb werde ich es erst gar nicht versuchen. Hier ist, was bei Ansatz Nr. 2 passiert.

$ sed 's/.*XXX \(.*\) ZZZ.*/\1/' data.txt 
Y1Y
Y2Y
AAAa YXX Y2Y ZZZ TT GGGG UU

Es findet also problemlos Übereinstimmungen, tut aber nichts für Zeilen, die nicht übereinstimmen. Es könnte eine Möglichkeit geben, seddas Löschen dieser Zeilen anzuweisen. In diesem Fall wäre dies eine alternative Lösung.

verwandte Informationen