msort(1)
dirancang untuk dapat mengurutkan file dengan catatan multi-baris. Ini memiliki gui opsional, serta versi baris perintah yang normal dan dapat digunakan untuk manusia. (Setidaknya, manusia yang suka membaca manual dengan cermat dan mencari contoh...)
AFAICT, Anda tidak dapat menggunakan pola arbitrer untuk catatan, jadi kecuali catatan Anda berukuran tetap (dalam byte, bukan karakter atau garis). msort
memang memiliki -b
opsi untuk rekaman yang merupakan blok baris yang dipisahkan oleh baris kosong.
Anda dapat mengubah input Anda menjadi format yang dapat digunakan dengan -b
cukup mudah, dengan meletakkan baris kosong sebelum setiap ###...
(kecuali yang pertama).
Secara default, ini mencetak statistik pada stderr, jadi setidaknya mudah untuk mengetahui saat tidak mengurutkan karena mengira seluruh masukan adalah satu catatan.
msort
bekerja pada data Anda. sed
perintah menambahkan baris baru ke setiap #+
baris kecuali untuk baris 1. -w
mengurutkan seluruh rekaman (secara leksikografis). Ada opsi untuk memilih bagian rekaman mana yang akan digunakan sebagai kunci, tetapi saya tidak membutuhkannya.
Saya juga mengabaikan pengupasan baris tambahan.
$ sed '2,$ s/^#\+/\n&/' unsorted.records | msort -b -w 2>/dev/null
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
Saya tidak beruntung dengan -r '#'
untuk menggunakannya sebagai pemisah rekaman. Diperkirakan seluruh file adalah satu catatan.
Solusinya adalah pertama-tama ubah umpan baris di dalam blok menjadi karakter pilihan Anda yang tidak terpakai ('|' dalam contoh di bawah), untuk mengurutkan hasilnya dan mengubah kembali pemisah yang dipilih ke umpan baris asli:
sed -e 'N; N; N; N; N; s/\n/|/g' file.txt \
| sort -k2,2 -t\| \
| sed 's/|/\n/g'
perl -0ne 'print sort /(#+[^#]*)/g' file.txt
perl -0
menyeruput seluruh file/(....)/g
cocokkan dan ekstrak catatanprint sort ...
mengurutkan dan mencetaknya