Bagaimana cara mengurutkan baris secara terpisah dalam beberapa "potongan" yang dipisahkan dengan header?

2

Pertanyaan ini saling melengkapi untuk yang satu ini: Urutkan paket garis menurut abjad . Setelah menjawab di sana, ternyata saya benar-benar salah memahami pertanyaan dan memecahkan masalah lain. Tidak ingin solusi saya dilupakan, saya memposting masalah di sini (dan solusi saya di bawah).


Pertimbangkan teks seperti:

[ProfileB]
param3=z
param2=y
param1=x
[ProfileA]
param1=k
param3=l
param2=

Saya perlu mengurutkan parameter dalam setiap [Profile*]blok secara terpisah. Contoh di atas harus diurutkan ke ini:

[ProfileB]
param1=x
param2=y
param3=z
[ProfileA]
param1=k
param2=
param3=l

Bagaimana saya bisa melakukannya dengan alat Unix / Linux standar?

Kamil Maciorowski
sumber

Jawaban:

2

Ini berfungsi di Debian saya:

sed '1 ! s/^\[/\x00\[/g' |
split -t '\0' -l 1 --filter='
   tr -d "\0" |
   { IFS="" read; printf "%s\n" "$REPLY"; sort; }
'

Untuk bekerja dengan file, gunakan pengalihan, misalnya { sed … ; } <input.txt >output.txt, di mana sed …seluruh perintah.

Prosedurnya adalah sebagai berikut:

  1. sedmenyisipkan karakter nol sebelum setiap [yang ada di awal baris, kecuali baris tersebut adalah yang pertama. Dengan cara ini, karakter nol memisahkan profil.
  2. splitmenghasilkan potongan, mengambil catatan yang dipisahkan oleh karakter nol, satu catatan per potongan. Alih-alih menulis ke file, splitpanggil filter untuk setiap chunk secara terpisah:
    1. pada awalnya trmenghapus karakter nol;
    2. kemudian readdan printfhanya echo baris pertama (header) dari potongan tersebut;
    3. akhirnya sortmelakukan tugasnya dengan jalur yang tersisa.
  3. Potongan diproses secara berurutan; outputnya adalah aliran tunggal.
Kamil Maciorowski
sumber