Wenn Ihre Absätze immer durch eine einzelne leere Zeile getrennt sind:
sed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n | \
sed 's/^\x03//;1s/\x03$//;1!G;h;$!d;$a\' | tr $'\003' \\n
Es ist ziemlich leicht zu sehen, wie es funktioniert, wenn man es in Stücke bricht und sed '/^$/s/^/\x02/' infile
dann rennt
sed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n
und so weiter ...
Wenn Ihre Absätze durch eine oder mehrere Leerzeilen getrennt sind, z
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
und Sie möchten die Reihenfolge der Absätze umkehren, aber die Reihenfolge der "leeren Blöcke" beibehalten. Sie können die Datei zweimal lesen:
1. Umfassen Sie Absätze in einzelne Zeilen (Entfernen leerer Blöcke dazwischen) und kehren Sie sie um und
2. Umdrehen Sie die leeren Blöcke In einzelne Zeilen "indizieren" Sie die Anzahl der leeren Zeilen in jedem Block (und entfernen nicht leere Zeilen),
dann paste
die Ergebnisse und verarbeiten die Ausgabe, um neue Zeilen wiederherzustellen:
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
welche Ausgänge:
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
Wenn Ihnen eine zusätzliche nachfolgende Zeile in der Ausgabe nichts ausmacht, können Sie die letzte löschen 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
Diese gehen davon aus, dass die erste und die letzte Zeile nicht leer ist (und nicht \x02
, \x03
oder \x04
im Eingang).