Ich habe eine Textdatei in diesem Format:
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
Ich möchte diese Datei KEY
zeilenweise sortieren und die nächsten 4 Zeilen mit dem Ergebnis belassen, also sollte das sortierte Ergebnis lauten:
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
Gibt es eine Möglichkeit, dies zu tun?
Antworten:
msort(1)
wurde entwickelt, um Dateien mit mehrzeiligen Datensätzen sortieren zu können. Es verfügt über eine optionale Benutzeroberfläche sowie eine normale und für Menschen verwendbare Befehlszeilenversion. (Zumindest Menschen, die Handbücher gerne sorgfältig lesen und nach Beispielen suchen ...)AFAICT, Sie können kein beliebiges Muster für Datensätze verwenden, es sei denn, Ihre Datensätze haben eine feste Größe (in Byte, keine Zeichen oder Zeilen).
msort
hat eine-b
Option für Datensätze, die durch Leerzeilen getrennte Zeilenblöcke sind.Sie können Ihre Eingabe in ein Format umwandeln, das
-b
problemlos funktioniert , indem Sie vor jede Zeile###...
(mit Ausnahme der ersten) eine Leerzeile einfügen .Standardmäßig werden Statistiken zu stderr ausgegeben. Zumindest ist es leicht zu erkennen, wann die Sortierung fehlgeschlagen ist, da die gesamte Eingabe für einen einzelnen Datensatz gehalten wurde.
msort
arbeitet an Ihren Daten. Mit demsed
Befehl wird jeder#+
Zeile mit Ausnahme von Zeile 1 eine neue Zeile vorangestellt.-w
Der gesamte Datensatz wird (lexikografisch) sortiert. Es gibt Optionen zum Auswählen des Teils eines Datensatzes, der als Schlüssel verwendet werden soll, aber ich habe sie nicht benötigt.Ich habe auch die zusätzlichen Zeilenumbrüche weggelassen.
Ich hatte kein Glück damit
-r '#'
, das als Datensatztrennzeichen zu verwenden. Es dachte, die ganze Datei sei ein Datensatz.quelle
msort
ist sehr nützlich; danke (etwa-r
scheint es, weil es mehr als eine # gibt, die ich verwendet habe-d
und es hat funktioniertmsort -qwr '#' ex
funktioniert bei mir (naja, es chagt den Output Rec. Separator)Eine Lösung besteht darin, zuerst die Zeilenumbrüche innerhalb eines Blocks in ein nicht verwendetes Zeichen Ihrer Wahl zu ändern ('|' im folgenden Beispiel), das Ergebnis zu sortieren und das ausgewählte Trennzeichen auf den ursprünglichen Zeilenumbruchs zurückzusetzen:
quelle
;N
dort 100 setzen , und es kann schwierig werden, ein Zeichen zu finden, das nicht im Text selbst verwendet wird. Es ist sehr gut fürsort
oderawk
... in der Lage sein, mehrzeilige Sortierungperl -0
schlürft die gesamte Datei/(....)/g
Ordne die Datensätze zu und extrahiere sieprint sort ...
sortiere und drucke siequelle
Hier ist eine andere Möglichkeit, die mit einer beliebigen Anzahl von Zeilen in einem
KEY
Abschnitt funktionieren sollte :Dies funktioniert, indem der Begrenzer in einer Variablen gespeichert wird (um ihn dann aus der Eingabe zu entfernen). Anschließend wird
KEY*
an jede Zeile in dem entsprechenden Abschnitt das ASCII-Zeichen angehängt , wobei ein niedrigesn
ASCII-l
Zeichen als Trennzeichen verwendet wird (das in Ihrer Eingabe wahrscheinlich nicht vorkommt). Anschließend werden alle Zeilen mit demselben Trennzeichen umnummeriert. Es ist dann nur noch eine Frage dessort
3. und 1. Feldes undcut
durchlaufen die mittlere Spalte zu tönen und dann die Begrenzer über ein Finale wiederherzustellensed
. Beachten Sie, dass bei den oben genanntenKEY12
SortiervorgängenKEY2
dersort
Befehl entsprechend Ihren Anforderungen angepasst wird.quelle
Sie können die POSIX Awk stdlib-Bibliothek verwenden :
quelle