awk -v RS= -v cmd=sort '{print | cmd; close(cmd); print ""}' file
Đặt dấu tách bản ghi RS
thành một chuỗi trống làm cho bước awk trong đoạn văn bản tại một thời điểm. Đối với mỗi đoạn, hãy đặt đoạn (in $0
) thành cmd (được đặt thành sort
) và in đầu ra. In ra một dòng trống để phân tách các đoạn đầu ra với a print ""
.
Nếu chúng tôi đưa ra các ví dụ perl, thì tôi sẽ trình bày một cách tiếp cận khác so với của Stephane:
perl -e 'undef $/; print join "\n", sort (split /\n/), "\n"
foreach(split(/\n\n/, <>))' < file
Bỏ đặt dấu tách trường ( undef $/
), điều này cho phép chúng ta sử dụng <>
và lấy toàn bộ STDIN. Chúng tôi sau split
đó xung quanh \n\n
(đoạn văn). foreach
"Đoạn", sort
các dòng bằng cách split
xoay quanh các dòng mới, sort
ing và sau đó join
đưa chúng trở lại với nhau và giải quyết một dấu vết \n
.
Tuy nhiên, điều này có một tác dụng phụ là thêm dấu phân cách "đoạn cuối" vào đoạn cuối (nếu trước đó không có đoạn nào). Bạn có thể vượt qua điều đó với một chút ít xinh đẹp:
perl -e 'undef $/; print join "\n", sort (split /\n/) , (\$_ == \$list[-1] ? "" : "\n")
foreach(@list = split(/\n\n/, <>))' < file
Điều này gán các đoạn cho @list
, và sau đó có một "hoạt động ternary" để kiểm tra xem đó có phải là phần tử cuối cùng của foreach
( \$_ == \$list[-1]
kiểm tra) không. in ""
nếu nó là ( ? ...
), other ( : ...
) in "\n"
cho tất cả các "đoạn" khác (các phần tử của @list
).
awk
giải pháp tránhsort
chi phí! Lén lút!