Auswählen eines Abschnitts einer Datei

Auswählen eines Abschnitts einer Datei

Ich habe eine Datei, die wie folgt formatiert ist:

title1
        line
        line

title2
        line
        line

        line

title3
        line
        line

und ich möchte den Abschnitt darunter extrahieren title2und den Einzug entfernen. Ich verwende derzeit Folgendes sed(aber awkoder ein Shell-Skript wäre in meinem Kontext geeignet, leider keine Sprachen wie perloder ):python

sed -n -e '/^title2$/,/^[a-zA-Z]/ { /^[a-zA-Z]/ d ; s/^[ \t]*// ; p }'

aber das lässt am Ende eine logisch leere Zeile übrig (logisch, weil sie Leerzeichen oder Tabulatoren enthalten kann). Ich möchte sie loswerden. Beachten Sie, dass es in dem zu behaltenden Teil möglicherweise andere logisch leere Zeilen gibt (oder ein /^[ \t]*$/ dhätte die Arbeit erledigt). Daher hätte ich gerne dieses Ergebnis:

line
line

line

Ich kann es mit einem zusätzlichen tun sed -e '$d', aber ich möchte wissen, ob es möglich ist, diesen zweiten Vorgang zu vermeiden.

Antwort1

Ich habe den Wartebereich genutzt und am Ende hatte ich

sed -ne '/^title2$/,/^[a-zA-Z]/ { /^title2$/ { n; h; b; } ; /^[a-zA-Z]/ d; H; x; s/[ \t]*//; P; s/.*\n//; x }'

das die von mir betreuten Fälle anscheinend korrekt behandelt.

Antwort2

  • Wenn es sich um eine "reine" Zeile handelt (ohne Tabulator oder Weiß), löschen Sie diese ebenfalls mit/^$/
  • für "logische" Blankonutzung/^\s*$/

    sed -n -e '/^title2:/,/^[a-zA-Z]/ { /^[a-zA-Z]/ d ; /^$/ d ; s/^[ \t]*// ; p }' 
    

Wo

  • /^$/Startzeile und Zeilenende abgleichen
  • /^\s*$/Übereinstimmung mit Startzeile, null oder mehr Leerzeichen oder Tabulatoren, Zeilenende

Antwort3

sed -n '/title2/,/^\S/ { //b; /^\s*$/ { N; /\n\S/q; P; D }; s/^\s*//; p }'

Ich habe dies ursprünglich getan, um die Aufmerksamkeit von @Archemar zu erregen. Ich wäre Ihnen sehr dankbar, wenn SieBitteAntwort anmein Kommentar in diesem Beitragwann immer du Zeit hast. Auch wenn die Antwort "Ich weiß nicht" ist. DANKE.

Zumindest in meiner Bash-Shell funktioniert es ohne -e. Ich bin nur neugierig, warum es überhaupt nötig ist. Und wenn\soder\Snicht unterstützt wird, können Sie sie durch [ \t]'s bzw. [^ \t]'s ersetzen.

Aufschlüsselung für Leute, die genauso ahnungslos waren wie ich, als ich diese Frage zum ersten Mal sah:

  • -nschaltet den automatischen Druck aus
  • /title2/,/^\S/ist ein Bereich, sedin dem gesucht werden soll (von der Zeile des ersten Vorkommens der Zeichenfolge " title2" bis zur nächsten Zeile, die mit einem Zeichen beginnt, das kein Leerzeichen ist [dh title3]einschließlich)
  • {bedeutet nur, die beigefügten Befehle auf den Bereich oder das Muster anzuwenden, das ich gerade angegeben habe
    • //bermöglicht, dass die folgenden Befehle nicht auf den Anfang und das Ende des Bereichs angewendet werden.
      Genauer gesagt, wenn Sie eine Übereinstimmung herstellen title2oder ^\Seinfach zum Ende des Skripts ( b) verzweigen (die nächste Zeile in der Datei verarbeiten, falls noch welche übrig sind), weil inGNUsed(BSDsagt ähnlich, bin mir nicht sicher, ob es eine andere Version davon gibt sed)

      '//' wiederholt die letzte Übereinstimmung mit dem regulären Ausdruck

    • /^\s*$/stimmt mit den „logisch leeren“ Zeilen im Bereich überein.
    • {
      • N; /\n\S/q;Wenn es sich also um eine „logisch leere“ Zeile handelt, Nwird die nächste Zeile zum Musterbereich hinzugefügt. Wenn es sich bei dieser nächsten Zeile jedoch um den nächsten Titel handelt, wird die Verarbeitung vollständig abgebrochen ( q), sodass weder die „logisch leere“ Zeile noch der nächste Titel gedruckt werden.
      • P; DWenn die „logisch leere“ Zeileist nichtgefolgt vom nächsten Titel, dannNurdie "logisch leere" Zeile wird gedruckt( P), und dannNurDie „logisch leere“ Zeile wird aus dem Musterbereich gelöscht, sodass die nächste Zeile, die durch Skript( ) zum Musterbereich hinzugefügt wurde, Nvom Anfang des Skripts an verarbeitet werden kann.D
    • }
    • s/^\s*//; pentfernt die Leerzeichen und Tabulatoren am Zeilenanfang und druckt die formatierte Zeile
  • }

@Archemar bitteHELFEN

verwandte Informationen