Nếu các đoạn văn của bạn luôn được phân tách bằng một dòng trống duy nhất:
sed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n | \
sed 's/^\x03//;1s/\x03$//;1!G;h;$!d;$a\' | tr $'\003' \\n
Thật dễ dàng để xem nó hoạt động như thế nào nếu bạn chia nó thành từng mảnh và chạy
sed '/^$/s/^/\x02/' infile
sau đó sed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n
...
Nếu các đoạn văn của bạn được phân tách bằng một hoặc nhiều dòng trống, vd
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
và bạn muốn đảo ngược thứ tự các đoạn văn nhưng giữ nguyên thứ tự của "các khối trống", bạn có thể đọc tệp hai lần: Thứ
nhất: biến các đoạn văn thành các dòng đơn (loại bỏ các khối trống ở giữa) và đảo ngược chúng và
thứ 2: biến các khối trống thành các dòng đơn, "lập chỉ mục" số lượng dòng trống trong mỗi khối (và loại bỏ các dòng không trống)
sau đó paste
kết quả và xử lý đầu ra để khôi phục dòng mới:
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
đầu ra nào:
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
Nếu bạn không nhớ một dòng dấu phụ trong đầu ra, bạn có thể bỏ dòng cuối cùng 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
Chúng giả định rằng dòng đầu tiên và dòng cuối cùng không trống (và không \x02
, \x03
hoặc \x04
trong đầu vào).