Wie lösche ich alle Zeilen in einer Datei ab einer übereinstimmenden Zeile?

83

Ich habe eine Datei, die aus mehreren Textzeilen besteht:

The first line
The second line
The third line
The fourth line

Ich habe eine Zeichenfolge, die eine der Zeilen ist: The second line

Ich möchte die Zeichenfolge und alle Zeilen danach in der Datei löschen, damit sie gelöscht wird The third lineund The fourth linezusätzlich zur Zeichenfolge. Die Datei würde werden:

The first line

Ich habe auf Google nach einer Lösung gesucht, und es scheint, dass ich verwenden sollte sed. Etwas wie:

sed 'linenum,$d' file

Aber wie findet man die Zeilennummer der Zeichenfolge? Oder wie soll ich es sonst machen?

DocWiki
quelle
Ihre Problemstellung ist widersprüchlich: "Ich möchte alle Zeilen nach der Zeile löschen" bedeutet, dass Sie nur zwei Zeilen löschen (wie Sie sagen), aber in Ihrer Beispielausgabe wird auch die Übereinstimmungszeile als fehlend angezeigt. Was willst du eigentlich?
Jonathan Leffler
Die passende Zeile UND alle Zeilen danach. Ich sollte mein Englisch verbessern. Vielen Dank für Ihre Informationen.
DocWiki
verwandte stackoverflow.com/questions/17364951/…
Trevor Boyd Smith

Antworten:

130

Wenn Sie die übereinstimmende Zeile (oder die folgenden Zeilen) nicht drucken möchten:

sed -n '/The second line/q;p' inputfile

Hier steht "Wenn Sie die Zeile erreichen, die dem Muster entspricht, beenden Sie, sonst drucken Sie jede Zeile". Die -nOption verhindert implizites Drucken und der pBefehl ist erforderlich, um Zeilen explizit zu drucken.

oder

sed '/The second line/,$d' inputfile

Dies besagt "Löschen Sie alle Zeilen aus der Ausgabe, beginnend mit der übereinstimmenden Zeile und bis zum Ende der Datei".

aber der erste ist schneller. Die Verarbeitung wird jedoch vollständig beendet. Wenn Sie also mehrere Dateien als Argumente haben, werden die Dateien nach der ersten übereinstimmenden Datei nicht verarbeitet. In diesem Fall ist das Löschformular besser.

Wenn Sie die übereinstimmende Zeile drucken möchten, jedoch keine der folgenden Zeilen:

sed '/The second line/q' inputfile

Hier steht "Alle Zeilen drucken und beenden, wenn die übereinstimmende Zeile erreicht ist" (die -nOption (kein impliziter Druck) wird nicht verwendet).

Weitere Informationen finden Sie unter man sed .

Bis auf weiteres angehalten.
quelle
3
Einige Befehle ärgern sich jedoch über Rohrbrüche ( co -pz. B. RCS ), und dann sind Sie mit der sed '/The second line/,$d'Notation besser dran .
Jonathan Leffler
Können Sie bitte Erklärungen hinzufügen?
Ahmad Abdelghany
@AhmadAbdelghany: Erklärungen hinzugefügt.
Bis auf weiteres angehalten.
@ TennisWilliamson Vielen Dank.
Ahmad Abdelghany
Bei der ersten Methode wird die letzte Zeile vor der übereinstimmenden Zeile zweimal ausgedruckt. Löschen der pAfter ;Works.
CrazyFrog
26

Dies ist etwas kürzer als bei anderen gegebenen Lösungen. Wenn Sie das Großbuchstaben Q beenden, wird das Drucken der aktuellen Zeile vermieden.

 sed '/The second line/Q' file

Um die Zeilen tatsächlich zu löschen, können Sie dieselbe Syntax verwenden.

 sed -i '/The second line/Q' file
jaap
quelle
1
Dies ist bei weitem meine Lieblingslösung.
TryTryAgain
5
sed '/The second line/q0' file

Oder ohne gnu sed:

sed '/The second line/q' file

Oder mit grep:

grep -B 9999999 "The second line"
Erik
quelle
Vielen Dank! Können Sie mir sagen, wie ich die Zeilennummer einer bestimmten Zeichenfolge finden kann, die ich noch nicht kenne?
DocWiki
grep -n Datei "Die zweite Zeile" | awk -F: '{print $ 1}'
Erik
@DocWiki: Du brauchst die Zeilennummer nicht; du suchst danach. sed "/$string/,\$d" inputfile.
Jonathan Leffler
5

Verwenden von awk (zeigt die übereinstimmende Linie nicht an)

awk '/pattern/ {exit} {print}' file.txt
Joel Arnold
quelle
Dies ist die beste Antwort, da Sie den Wert der zweiten Zeile möglicherweise nicht kennen.
RonJohn
0

Fügen Sie zuerst die Zeilennummer hinzu und löschen Sie die Zeile

cat new.txt 
The first line
The second line
The third line
The fourth line

 cat new.txt  | nl
     1  The first line
     2  The second line
     3  The third line
     4  The fourth line



cat new.txt  | nl | sed  "/2/d"
     1  The first line
     3  The third line
     4  The fourth line

cat new.txt  |  nl |sed  "3d;4d"
     1  The first line
     2  The second line

mit awk

awk 'NR!=3 && NR!=4' new.txt 
The first line
The second line
sush
quelle
0
awk '/The second line/{exit}1' file
kurumi
quelle