2 Stimmen

Das Lesen einer Untermenge 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? Das heißt, 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

Ihr Beispiel reicht nicht aus, um im Allgemeinen zu bestimmen, was Sie wollen, aber wenn Sie annehmen, dass Sie die erste und letzte Zeile entfernen möchten, können Sie einfach verwenden

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

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

3voto

ghostdog74 Punkte 305138

Für ihren Satz von 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 mit bash tatsächlich nur die Bash gemeint ist, kann ich dir nicht helfen. Du solltest wirklich die richtigen Tools für den Job verwenden. Wenn du standardmäßige UNIX-Dienstprogramme meinst, die du von der Bash aus aufrufen kannst, würde ich dafür awk verwenden.

echo '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' | awk '
    BEGIN {e=0}
    /^Zeile b/ {e=1}
    /^Zeile d/ {if (e==1) {print;exit}}
    {if (e==1) print}
'

Dies gibt aus:

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

Die Funktionsweise ist einfach.

  • e ist der Echo-Flag, anfangs auf false (0) gesetzt.
  • Wenn du Zeile b findest, setze Echo auf true (1) - drucke noch nicht. Das wird vom letzten Punkt unten gehandhabt.
  • Wenn du Zeile d findest und Echo aktiv ist, drucke sie und beende.
  • Wenn Echo aktiv ist, drucke die Zeile (das beinhaltet auch Zeile b).

Ich gehe hier davon aus, dass du nicht bei einer Zeile d beenden möchtest, es sei denn, du echoest bereits. Wenn das falsch ist, verschiebe das Beenden außerhalb der if-Anweisung für Zeile d:

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

Dann, wenn du eine Zeile d vor deiner Zeile b bekommst, wird es einfach beenden, ohne etwas zu echoen.

Die "/^Zeile X/"-artigen Klauseln können sehr leistungsstark gemacht werden, um praktisch alles zu passen, was du ihm entgegenwirfst.

1voto

Sie können es nur mit Bash machen, obwohl ich Pax zustimme, dass die Verwendung anderer Tools wahrscheinlich eine bessere Lösung ist. Hier ist eine reine Bash-Lösung:

while read line
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