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?


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

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 .


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

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"

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

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.