Zeichenfolgenmuster in Datei/Eingabe finden, kontextabhängige Suche (nicht wie grep)

Zeichenfolgenmuster in Datei/Eingabe finden, kontextabhängige Suche (nicht wie grep)

Gibt es ein Dienstprogramm zum Suchen von Text, wie in grep(Linux) oder findstr(DOS), das die Suche jedoch erst beginnt, wenn ein anderer vorgegebener Text/ein anderes vorgegebenes Muster gefunden wurde?

Wie der Versuch, einen bestimmten Text/ein bestimmtes Muster in einer Datei zu finden, aber nur die, die sich in einem bestimmten Abschnitt der Datei befinden. Nur „die Datei“ ist in meinem Fall eine Ausgabe eines anderen Programms und die Anzahl der ausgegebenen Zeilen ist zu groß, um sie in eine Datei zu schreiben und dort zu analysieren.

Beispiel:

section ONE
  text_a
  text_b
  text_c
section TWO
  text_b
  text_c
section THREE
  . . .

Suchen Sie, ob nur in Abschnitt ZWEI ein „text_c“ vorhanden ist.

Ich habe versucht, die Optionen zu lesen grep, aber es scheint diese Möglichkeit nicht zu geben. Dies soll auch die Anzahl der Zeichenfolgenvergleiche minimieren, da „text_c“ viel länger ist als Abschnittsnamen.

Antwort1

Betrachten wir diese Testdatei:

$ cat file
section ONE
  text_a
  text_b
  text_c  <-ignore this
section TWO
  text_b
  text_c  <-keep this
section THREE
  text_a
  text_b
  text_c  <-ignore this

Um eine beliebige Zeile auszuwählen, text_cdie Folgendes enthält section TWO:

$ awk '/^section/{f=0} /^section TWO/{f=1} f && /text_c/' file
  text_c  <-keep this

Wenn die Eingabe nicht aus einer Datei, sondern aus generiert wird command, verwenden Sie:

command | awk '/^section/{f=0} /^section TWO/{f=1} f && /text_c/'

Wie es funktioniert

  • /^section/{f=0}

    Immer wenn wir eine Zeile finden, die mit beginnt section, setzen wir f=0.

  • /^section TWO/{f=1}

    Wenn die Zeile mit beginnt section TWO, dann überschreiben Sie den vorherigen Befehl und legen Sie fest f=1.

  • f && /text_c/

    Wenn fungleich Null ist und die aktuelle Zeile übereinstimmt text_c, dann drucken Sie die Zeile.

Antwort2

Sie können dies auch sedfolgendermaßen tun:

command | sed -n -e '/section TWO/,/section THREE/ { /text_c/p;}'

Dies funktioniert durch:

  • -nweist darauf hin sed, dass übereinstimmende Zeilen standardmäßig nicht gedruckt werden sollen
  • -egibt sedein Skript zum Bearbeiten vor
    • /section TWO/,/section THREE/legt unseren Adressbereich fest, daher wenden wir die nächste Funktion auf alle Zeilen zwischen den übereinstimmenden Zeilen an section TWOundsection THREE
    • { /text_c/p;}definiert die Funktion, die eine Zeile findet und diese ausgibt, text_cwenn sie sie findetp

Antwort3

Wenn die Anzahl der Zeilen, die jedem Abschnitt folgen, einigermaßen konstant ist, können Sie die Funktion „-A“ verwenden.X'-Option in grep zum DruckenXZeilen, die auf eine Abschnittsübereinstimmung folgen. Dies kann dann an ein zweites Grep weitergeleitet werden, das in „Abschnitt ZWEI“ nach Ihrem Muster sucht.

$ cat file
section ONE
  1 text_a
  1 text_b
  1 text_c  
section TWO
  2_text_a
  2 text_b
  2 text_c  
section THREE
  3 text_a
  3 text_b
  3 text_c 

$ grep -A3 'section TWO' file | grep text_c
  2 text_c

verwandte Informationen