awk -v RS= -v cmd=sort '{print | cmd; close(cmd); print ""}' file
L'impostazione del separatore di record RSsu una stringa vuota fa un passaggio di awk nei paragrafi alla volta. Per ogni paragrafo, reindirizzare il paragrafo (in $0) a cmd (che è impostato su sort) e stampare l'output. Stampa una riga vuota per separare i paragrafi di output con a print "".
Se diamo esempi perl, presento un approccio alternativo rispetto a quello di Stephane:
perl -e 'undef $/; print join "\n", sort (split /\n/), "\n"
foreach(split(/\n\n/, <>))' < file
Disinserire il separatore di campo ( undef $/), questo ci consente di utilizzare <>e ottenere l'intero STDIN. Abbiamo poi splitquello intorno \n\n(paragrafi). foreach"paragrafo", sortle linee splitruotando attorno a nuove linee, sorting e poi joinrimettendole insieme e virando su un finale \n.
Tuttavia, ciò ha un effetto collaterale nell'aggiungere un separatore "paragrafo finale" sull'ultimo paragrafo (se non ne aveva uno prima). Puoi aggirare quello con il leggermente meno carino:
perl -e 'undef $/; print join "\n", sort (split /\n/) , (\$_ == \$list[-1] ? "" : "\n")
foreach(@list = split(/\n\n/, <>))' < file
Questo assegna i paragrafi a @list, e quindi c'è una "operazione ternaria" per verificare se è l'ultimo elemento del foreach(il \$_ == \$list[-1]controllo). stampa ""se è ( ? ...), else ( : ...) stampa "\n"per tutti gli altri "paragrafi" (elementi di @list).
awksoluzione che evita lesortspese generali! Subdolo!