Sort
如何根據每個部分第一行的第四個值對文件部分進行排序?
我有一個由空行分隔的不同部分的文件,我想根據每個部分的第一行的第四個值對所有部分進行升序排序,保持每個部分的主體不變。
範例輸入
PT2 energy = 7.135 eV ( -459.5928710 au) ( 57545.0 cm-1) (R=4) 22u22d00 3->6 : -0.535 (0.286) 22202200 4-->6 : -0.344 (0.119) 222u200d 4->8 : 0.256 (0.065) 222u2d00 4->6 : -0.254 (0.065) R=4 TDM-form-state 1= 0.2702 -0.2855 -0.5610 TDM= 0.69 f: 0.082 PT2 energy = 7.018 eV ( -459.5971543 au) ( 56605.0 cm-1) (R=5) 22u220d0 3->7 : -0.396 (0.156) 222u2d00 4->6 : 0.352 (0.124) 22220ud0 5-->6,7 : 0.326 (0.106) 2222u0d0 5->7 : 0.303 (0.092) 2222u00d 5->8 : 0.271 (0.073) 222ud020 4,5-->7 : 0.267 (0.071) 22u22d00 3->6 : -0.229 (0.052) R=5 TDM-form-state 1= 0.0860 -0.1785 -0.5446 TDM= 0.58 f: 0.058 PT2 energy = 6.552 eV ( -459.6143027 au) ( 52841.3 cm-1) (R=6) 222u20d0 4->7 : -0.612 (0.374) 2222ud00 5->6 : -0.499 (0.249) 222udud0 4,5-->6,7 : -0.271 (0.074) R=6 TDM-form-state 1= -0.2916 -0.0544 -2.1475 TDM= 2.17 f: 0.754
出局
PT2 energy = 6.552 eV ( -459.6143027 au) ( 52841.3 cm-1) (R=6) 222u20d0 4->7 : -0.612 (0.374) 2222ud00 5->6 : -0.499 (0.249) 222udud0 4,5-->6,7 : -0.271 (0.074) R=6 TDM-form-state 1= -0.2916 -0.0544 -2.1475 TDM= 2.17 f: 0.754 PT2 energy = 7.018 eV ( -459.5971543 au) ( 56605.0 cm-1) (R=5) 22u220d0 3->7 : -0.396 (0.156) 222u2d00 4->6 : 0.352 (0.124) 22220ud0 5-->6,7 : 0.326 (0.106) 2222u0d0 5->7 : 0.303 (0.092) 2222u00d 5->8 : 0.271 (0.073) 222ud020 4,5-->7 : 0.267 (0.071) 22u22d00 3->6 : -0.229 (0.052) R=5 TDM-form-state 1= 0.0860 -0.1785 -0.5446 TDM= 0.58 f: 0.058 PT2 energy = 7.135 eV ( -459.5928710 au) ( 57545.0 cm-1) (R=4) 22u22d00 3->6 : -0.535 (0.286) 22202200 4-->6 : -0.344 (0.119) 222u200d 4->8 : 0.256 (0.065) 222u2d00 4->6 : -0.254 (0.065) R=4 TDM-form-state 1= 0.2702 -0.2855 -0.5610 TDM= 0.69 f: 0.082
我試過了
sort -n -k4 file
但這對所有文件都進行了操作並破壞了這些部分
使用任何 awk、排序和剪切:
$ awk -v OFS='\t' '!pNF{val=$4} {print val, NR, $0; pNF=NF} END{if (pNF) print val, NR+1, ""}' file | sort -k1,1n -k2,2n | cut -f3- PT2 energy = 6.552 eV ( -459.6143027 au) ( 52841.3 cm-1) (R=6) 222u20d0 4->7 : -0.612 (0.374) 2222ud00 5->6 : -0.499 (0.249) 222udud0 4,5-->6,7 : -0.271 (0.074) R=6 TDM-form-state 1= -0.2916 -0.0544 -2.1475 TDM= 2.17 f: 0.754 PT2 energy = 7.018 eV ( -459.5971543 au) ( 56605.0 cm-1) (R=5) 22u220d0 3->7 : -0.396 (0.156) 222u2d00 4->6 : 0.352 (0.124) 22220ud0 5-->6,7 : 0.326 (0.106) 2222u0d0 5->7 : 0.303 (0.092) 2222u00d 5->8 : 0.271 (0.073) 222ud020 4,5-->7 : 0.267 (0.071) 22u22d00 3->6 : -0.229 (0.052) R=5 TDM-form-state 1= 0.0860 -0.1785 -0.5446 TDM= 0.58 f: 0.058 PT2 energy = 7.135 eV ( -459.5928710 au) ( 57545.0 cm-1) (R=4) 22u22d00 3->6 : -0.535 (0.286) 22202200 4-->6 : -0.344 (0.119) 222u200d 4->8 : 0.256 (0.065) 222u2d00 4->6 : -0.254 (0.065) R=4 TDM-form-state 1= 0.2702 -0.2855 -0.5610 TDM= 0.69 f: 0.082
否則只有 GNU awk 用於數組數組和 sorted_in:
awk ' BEGIN { RS=""; ORS="\n\n" } { recs[$4][++cnt[$4]] = $0 } END { PROCINFO["sorted_in"] = "@ind_num_asc" for (val in recs) { for (i=1; i<=cnt[val]; i++) { print recs[val][i] } } } ' file
循環
cnt[]
是這樣,如果/當相同的值(例如7.135
)在不同輸入記錄的第 4 個欄位中多次出現時,輸出將保留該鍵值的輸入順序。或者,您可以在讀取輸入時通過字元串連接獲得相同的結果,例如仍然使用 GNU awk 進行 sorted_in:awk ' BEGIN { RS=""; ORS="\n\n" } { recs[$4] = recs[$4] $0 ORS } END { PROCINFO["sorted_in"] = "@ind_num_asc" for (val in recs) { printf "%s", recs[val] } } ' file
僅 gawk 方法的缺點是它們必須將整個文件儲存在記憶體中,並且它們不能移植到沒有 gawk 的系統。頂部的 awk+sort+cut 腳本是高度可移植的,只有“排序”必須一次處理整個文件,它被設計為使用按需分頁等來處理大文件,因此不太可能有一個比 gawk 大的文件的問題。