2 Stimmen

Das Lesen einer Teilmenge der Zeilen in einer Textdatei mit Bash

Ich habe eine Datei

Zeile a - das ist Zeile a
Zeile b - das ist Zeile b
Zeile c - das ist Zeile c
Zeile d - das ist Zeile d
Zeile e - das ist Zeile e

Die Frage ist: Wie kann ich die Zeilen von "Zeile b" bis "Zeile d" mit Bash-Befehlen ausgeben? Ich meine, um zu erhalten:

"Zeile b - das ist Zeile b
 Zeile c - das ist Zeile c
 Zeile d - das ist Zeile d"

5voto

ghostdog74 Punkte 305138
sed -n '/Zeile b/,/Zeile d/p' Datei

3voto

Paolo Capriotti Punkte 3974

Dein Beispiel reicht nicht aus, um zu schließen, was du im Allgemeinen möchtest, aber wenn du annehmen möchtest, dass du die erste und letzte Zeile entfernen möchtest, kannst du einfach verwenden

tail -n+2 $filename | head -n-1

Hier druckt tail -n+2 alle Zeilen ab der zweiten Zeile aus, und head -n-1 druckt alle Zeilen außer der letzten aus.

3voto

ghostdog74 Punkte 305138

Für Ihren Satz Beispieldaten:

awk '/Zeile b/,/Zeile d/' Datei

Oder

awk '/Zeile d/{f=0;print}/Zeile b/{f=1}f' Datei

2voto

paxdiablo Punkte 809679

Wenn Sie mit "Bash" tatsächlich nur die Bash meinen, kann ich Ihnen nicht helfen. Sie sollten wirklich die richtigen Werkzeuge für den Job verwenden. Wenn Sie jedoch die standardmäßigen UNIX-Dienstprogramme meinen, die Sie von der Bash aus aufrufen können, würde ich dafür awk verwenden.

echo 'Zeile a - dies ist Zeile a
Zeile b - dies ist Zeile b
Zeile c - dies ist Zeile c
Zeile d - dies ist Zeile d
Zeile e - dies ist Zeile e' | awk '
    BEGIN {e=0}
    /^Zeile b/ {e=1}
    /^Zeile d/ {if (e==1) {print;exit}}
    {if (e==1) print}
'

Dies gibt aus:

Zeile b - dies ist Zeile b
Zeile c - dies ist Zeile c
Zeile d - dies ist Zeile d

Das Funktionsprinzip ist einfach.

  • e ist der Echo-Indikator, zu Beginn auf falsch (0) gesetzt.
  • Wenn Sie Zeile b finden, setzen Sie Echo auf wahr (1) - noch nicht drucken. Dies wird durch den letzten Punkt unten behandelt.
  • Wenn Sie Zeile d finden und Echo aktiv ist, drucken Sie es und beenden Sie.
  • Wenn Echo aktiv ist, drucken Sie die Zeile (das beinhaltet Zeile b).

Ich habe hier die Annahme gemacht, dass Sie bei einer Zeile d nicht beenden möchten, es sei denn, Sie echoen bereits. Wenn das falsch ist, verschieben Sie das exit außerhalb der if-Anweisung für die Zeile d:

    /^Zeile d/ {if (e==1) print;exit}

Dann, wenn Sie eine Zeile d vor Ihrer Zeile b erhalten, wird einfach ohne etwas zu echoen beendet.

Die "/^Zeile X/"-artigen Klauseln können sehr leistungsstark gemacht werden, um praktisch alles zu finden, was Sie ihnen vorwerfen.

1voto

Sie können es nur mit Bash machen, obwohl ich Pax zustimme, dass es wahrscheinlich eine bessere Lösung ist, andere Werkzeuge zu verwenden. Hier ist eine reine Bash-Lösung:

whileread 
do
    t=${line#line b}
    if test "$t" != "$line"
    then
        echo $line
        while read line
        do
            echo $line
            t=${line#line d}
            if test "$t" != "$line"
            then
                exit 0
            fi
        done
    fi
done

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X