Ich habe eine Datei mit Text in Absätzen (Zeilen mit Text durch eine oder mehrere leere Zeilen getrennt). Ich möchte die Reihenfolge der Absätze umkehren (dh der letzte Absatz wird der erste, ...), vorzugsweise mit sed.
Ich suche nach einem sed-Befehl, der mit einer Datei mit Absätzen und tac
mit einer Datei mit Zeilen funktioniert.
quelle
Es könnte einen Weg geben, dies zu tun
sed
, aber ich bezweifle, dass es einfach sein wird. So würde ich es in Perl machen:Dies funktioniert, weil das Definieren des Trennzeichens für Eingabedatensätze als Nullzeichen (
-00
) Perl anweist, im Absatzmodus zu arbeiten. Perls Definition eines Absatzes 1 entspricht genau Ihrer Definition.1 Schauen Sie unter die Überschrift
Other values for $/
quelle
Wenn Ihre Absätze immer durch eine einzelne leere Zeile getrennt sind:
Es ist ziemlich leicht zu sehen, wie es funktioniert, wenn man es in Stücke bricht und
sed '/^$/s/^/\x02/' infile
dann renntsed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n
und so weiter ...Wenn Ihre Absätze durch eine oder mehrere Leerzeilen getrennt sind, z
und Sie möchten die Reihenfolge der Absätze umkehren, aber die Reihenfolge der "leeren Blöcke" beibehalten. Sie können die Datei zweimal lesen:
1. Umfassen Sie Absätze in einzelne Zeilen (Entfernen leerer Blöcke dazwischen) und kehren Sie sie um und
2. Umdrehen Sie die leeren Blöcke In einzelne Zeilen "indizieren" Sie die Anzahl der leeren Zeilen in jedem Block (und entfernen nicht leere Zeilen),
dann
paste
die Ergebnisse und verarbeiten die Ausgabe, um neue Zeilen wiederherzustellen:welche Ausgänge:
Wenn Ihnen eine zusätzliche nachfolgende Zeile in der Ausgabe nichts ausmacht, können Sie die letzte löschen
sed
:Diese gehen davon aus, dass die erste und die letzte Zeile nicht leer ist (und nicht
\x02
,\x03
oder\x04
im Eingang).quelle
Sie können es mit einer einzelnen Instanz von tun
sed
; Keine Rohre notwendig. Dased
das Dokument nur einmal durchlaufen wird und sich der als Beginn der Ausgabe erforderliche Teil der Datei am Ende der Datei befindet, muss die gesamte Datei im Speichersed
(im Speicherbereich) gespeichert werden nicht gut skalieren. Aber es beantwortet die Frage genau:Wenn kein nachfolgender Zeilenumbruch vorhanden ist, funktioniert dies weiterhin einwandfrei. Wenn es eine einzelne nachfolgende neue Zeile gibt, wird sie in der Ausgabe unterdrückt (dh es wird keine führende neue Zeile in der Ausgabe vorhanden sein). Wenn die Eingabe (zum Beispiel) 5 nachfolgende Zeilenumbrüche enthält, enthält die Ausgabe 4 führende Zeilenumbrüche.
Die Lücken zwischen den Absätzen bleiben erhalten.
Leerzeichen in einer ansonsten leeren Zeile werden NICHT als Absatzumbruch behandelt, aber das ist eine Funktion, kein Fehler. :) :)
Sie können dies auch als viel weniger lesbarer Einzeiler tun:
Dies funktioniert zwar nur mit GNU
sed
. (Beachten Sie die schwierige Verwendung von Backreferences für die Ausführungs/$/\n/
. Ohne diese wäre es kein wörtlicher Einzeiler, da es einen Backslash-Newline enthalten würde.)quelle
G;h
. Sie könnten etwas über Eingabebeschränkungen oder ähnliches erwähnen.sed
Hand habe, aber die Skriptversion bewahrt definitiv die Lücken zwischen den Absätzen. Ich habe es gerade auf Ihre Eingabe getestet. Haben Sie die Skriptversion getestet?Dies sollte Ihren
sed
Absatzabstand beibehalten (während es besser lesbar ist als :)).quelle