Mam plik tekstowy w tym formacie:
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
Chcę posortować ten plik według KEY
linii i zachować w nim kolejne 4 wiersze, więc posortowany wynik powinien wyglądać następująco:
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
czy jest na to sposób?
Odpowiedzi:
msort(1)
został zaprojektowany, aby móc sortować pliki z rekordami wieloliniowymi. Ma opcjonalne GUI, a także normalną i użyteczną dla ludzi wersję wiersza poleceń. (Przynajmniej ludzie, którzy lubią uważnie czytać podręczniki i szukają przykładów ...)AFAICT, nie możesz użyć dowolnego wzorca dla rekordów, więc chyba że twoje rekordy mają stały rozmiar (w bajtach, a nie znakach lub wierszach).
msort
ma-b
opcję dla rekordów, które są blokami linii oddzielonymi pustymi liniami.Możesz przekształcić swoje dane wejściowe w format, który będzie działał
-b
dość łatwo, umieszczając pusty wiersz przed każdym###...
(oprócz pierwszego).Domyślnie drukuje statystyki na stderr, więc przynajmniej łatwo jest stwierdzić, kiedy nie posortował, ponieważ uważał, że całe wejście było pojedynczym rekordem.
msort
działa na twoich danych.sed
Polecenie poprzedza nowego wiersza do każdej#+
linii z wyjątkiem linii 1.-w
sortuje cały rekord (leksykograficznie). Istnieją opcje wybierania, której części rekordu użyć jako klucza, ale nie potrzebowałem ich.Pominąłem również usuwanie nowych linii.
Nie miałem szczęścia
-r '#'
użyć tego jako separatora rekordów. Myślał, że cały plik to jedna płyta.źródło
msort
jest bardzo przydatny; dzięki (-r
wydaje się, że jest tak, ponieważ użyłem więcej niż jednego # i użyłem-d
i zadziałałomsort -qwr '#' ex
działa dla mnie (cóż, wydziela separatorRozwiązaniem jest najpierw zmiana wysuwu wiersza w bloku na wybrany nieużywany znak („|” w poniższym przykładzie), posortowanie wyniku i powrót wybranego separatora do oryginalnego wysuwu wiersza:
źródło
;N
tam wstawić 100 , a znalezienie znaku, który nie jest używany w samym tekście, może być trudne; bardzo dobrze nadaje się do ...sort
lubawk
sortowania wielowierszowegoperl -0
slurps cały plik/(....)/g
dopasuj i wyodrębnij rekordyprint sort ...
posortuj je i wydrukujźródło
Oto inny sposób, który powinien działać z dowolną liczbą linii w
KEY
sekcji:Działa to poprzez zapisanie separatora w zmiennej (a następnie usunięcie go z wejścia). Następnie dodaje
KEY*
znak do każdej linii w odpowiedniej sekcji, używając niskiego znaku ascii (co prawdopodobnie nien
pojawi się na wejściu) jako separatora, a następnie analizuje wszystkiel
ines przy użyciu tego samego separatora. Jest to tylko kwestia wejściasort
przez 3. i 1. pole icut
wybrania środkowej kolumny, a następnie przywrócenia ograniczników przez finałsed
. Zauważ, że z powyższym,KEY12
posortujesz przedtem,KEY2
więc dostosujsort
polecenie do swoich potrzeb.źródło
Możesz użyć biblioteki stdlib Awk POSIX :
źródło