Ich habe eine Textdatei mit vertauschten Zeilen, die mit 'TITLE' und 'DATA' beginnen, aber manchmal gibt es doppelte Zeilen, die mit 'TITLE' beginnen:
TITEL etwas Daten einige Daten TITEL etwas anderes DATA einige andere Daten TITEL noch etwas mehr TITLE Zusatzinfo
DATEN etwas mehr Daten
Ich möchte die doppelten Zeilen erkennen, die mit "TITLE" beginnen und nur die erste Zeile jedes Paares behalten.
Ich habe herausgefunden, dass der reguläre Ausdruck für das Erfassen dieser ^TITLE.*\n^TITLE.*\n
ist, jetzt möchte ich dies in einen einzeiligen perl
/ bash
/ sed
/ awk
Befehl integrieren, der die zweite Zeile entfernt und gib den Rest der Datei aus, aber ich konnte das nicht herausfinden.
Hier ist eine Möglichkeit, wie Sie es mit GNU sed tun können:
%Vor%N
fügt eine zweite Zeile in den Musterbereich ein. TITLE
beginnen. P; D
druckt und löscht die erste Zeile im Musterbereich. Ausgabe:
%Vor% Wie von Nikina Reklawyks in den Kommentaren erwähnt, funktioniert die obige Lösung nur mit zwei aufeinanderfolgenden Zeilen beginnend mit TITLE
, um beliebig viele Wiederholungen zu bewältigen, eine einfache Schleife kann wie folgt hinzugefügt werden:
Die ta
-Anweisung bewirkt, dass sed zum :a
-Label springt, wenn s///
erfolgreich ist.
Eine andere Möglichkeit wäre, den uniq
-Befehl von coreutils
zu verwenden, dies ist nicht so flexibel, funktioniert aber in diesem Fall trotzdem gut:
Es klingt für mich so, als hätten Sie Datensätze, die aus zwei Feldern bestehen, TITLE und DATA, und wenn Sie das zweite Feld verpassen, möchten Sie den Datensatz löschen. Aber das hast du in deiner Frage nicht gefragt. Also hier ist eine Möglichkeit zu tun, was Sie gefragt haben:
%Vor%Die Idee hier ist, dass wir eine Variable auf einen TITEL setzen werden, wenn wir sie sehen und nicht schon eine betitelte Menge haben, dann drucken wir sie nur, wenn wir eine DATEN sehen. Dies funktioniert für die eingegebenen Daten, wenn ich Ihre Frage richtig gelesen habe. Ausgabe ist:
%Vor%Wie Sie sehen, wurde die letzte TITLE-Zeile in Ihrem Dataset gelöscht.
Und hier ist ein anderer Weg, dies in awk zu tun ...
%Vor% In diesem Fall überspringt der erste Ausdruck Titel, wenn t
festgelegt wurde. Der zweite Ausdruck setzt t
nicht richtig. Der dritte Ausdruck legt fest, ob für Titel und der letzte Ausdruck ( 1
) die Zeile ausgibt. Natürlich werden die letzten drei Ausdrücke nicht ausgeführt, wenn wir die Zeile im ersten Ausdruck übersprungen haben. Es erzeugt die gleiche Ausgabe wie oben und schaut nicht auf /^DATA/
.
Schließlich ist dies der kleinste Code, aber die seltsamste Logik:
%Vor% Er druckt alle Datenzeilen oder jede Zeile, in der t
nicht gesetzt ist, und setzt t
effektiv auf einen booleschen Wert, was sich auf die Auswertung der nächsten Zeile auswirkt. Wenn Sie dies in csh oder tcsh tun, achten Sie auf das Ausrufezeichen, das in diesen Shells möglicherweise maskiert werden muss.