Si vos paragraphes sont toujours séparés par une seule ligne vide:
sed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n | \
sed 's/^\x03//;1s/\x03$//;1!G;h;$!d;$a\' | tr $'\003' \\n
Il est assez facile de voir comment cela fonctionne si vous le divisez en morceaux et exécutez
sed '/^$/s/^/\x02/' infile
ensuite sed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n
et ainsi de suite ...
Si vos paragraphes sont séparés par une ou plusieurs lignes vides, par exemple
Para 1 line 1
Para 1 line 2
Para 2 line 1
Para 3 line 1
Para 3 line 2
Para 4 line 1
Para 4 line 2
Para 5 line 1
et vous souhaitez inverser l'ordre des paragraphes mais conserver l'ordre des "blocs vides", vous pouvez lire le fichier deux fois:
1er: transformer les paragraphes en lignes simples (en supprimant les blocs vides entre les deux) et les inverser et
2e: tourner les blocs vides en lignes simples, "indexant" le nombre de lignes vides dans chaque bloc (et supprimant les lignes non vides)
puis paste
les résultats et traitent la sortie pour restaurer les retours à la ligne:
paste -d $'\004' <(sed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n | \
sed -e '/^\x03$/d;s/^\x03//;s/\x03$//;1!G;h;$!d;$a\') \
<(sed -E '/^$/!d;//{:a;N;/^(\n){1,}$/ba;s/\n/\x02/g;s/(.*)\x02.*/\1/}' infile) \
| sed '$!s/\x04/\n/;$s/\x04$//' | tr $'\003\002' \\n\\n
qui génère:
Para 5 line 1
Para 4 line 1
Para 4 line 2
Para 3 line 1
Para 3 line 2
Para 2 line 1
Para 1 line 1
Para 1 line 2
Si cela ne vous dérange pas une ligne de fin supplémentaire dans la sortie, vous pouvez supprimer la dernière sed
:
paste -d $'\n' <(sed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n | \
sed -e '/^\x03$/d;s/^\x03//;s/\x03$//;1!G;h;$!d;$a\') \
<(sed -E '/^$/!d;//{:a;N;/^(\n){1,}$/ba;s/\n/\x02/g;s/(.*)\x02.*/\1/}' infile) | \
tr $'\003\002' \\n\\n
Ceux-ci supposent que la première et la dernière ligne ne sont pas vides (et non \x02
, \x03
ou \x04
dans l'entrée).