Se seus parágrafos são sempre separados por uma única linha vazia:
sed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n | \
sed 's/^\x03//;1s/\x03$//;1!G;h;$!d;$a\' | tr $'\003' \\n
É muito fácil ver como ele funciona se você quebrá-lo em pedaços e executar
sed '/^$/s/^/\x02/' infile
, em seguida, sed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n
e assim por diante ...
Se seus parágrafos estiverem separados por uma ou mais linhas vazias, por exemplo,
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
e você deseja reverter a ordem dos parágrafos, mas preservar a ordem dos "blocos vazios", você pode ler o arquivo duas vezes:
1º: transformar parágrafos em linhas únicas (removendo os blocos vazios no meio) e invertê-los e
2º: virar os blocos vazios em linhas únicas, "indexando" o número de linhas vazias em cada bloco (e removendo as linhas não vazias),
depois paste
os resultados e processe a saída para restaurar novas linhas:
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
quais saídas:
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
Se você não se importa com uma linha de fuga extra na saída, pode soltar a última 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
Eles assumem que a primeira e a última linha não estão vazias (e não \x02
, \x03
ou \x04
na entrada).