awk -v RS= -v cmd=sort '{print | cmd; close(cmd); print ""}' file
Đặt dấu tách bản ghi RSthà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", sortcác dòng bằng cách splitxoay quanh các dòng mới, sorting 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).
awkgiải pháp tránhsortchi phí! Lén lút!