Если ваши абзацы всегда разделены одной пустой строкой:
sed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n | \
sed 's/^\x03//;1s/\x03$//;1!G;h;$!d;$a\' | tr $'\003' \\n
Это довольно легко увидеть , как это работает , если вы разбить его на куски и работать
sed '/^$/s/^/\x02/' infileпотом sed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\nи так далее ...
Если ваши абзацы разделены одной или несколькими пустыми строками, например
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
и вы хотите изменить порядок абзацев, но сохранив порядок «пустых блоков», вы можете прочитать файл дважды:
1-й: превратить абзацы в одну строку (удаляя пустые блоки между ними) и повернуть их вспять и
2-й: превратить пустые блоки в отдельные строки «индексируют» количество пустых строк в каждом блоке (и удаляют непустые строки),
затем pasteрезультаты и обрабатывают выходные данные для восстановления новых строк:
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
какие выводы:
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
Если вы не возражаете против дополнительной строки в выводе, вы можете оставить последнюю 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
Они предполагают, что первая и последняя строки не пусты (и нет \x02, \x03или \x04во входных данных).