文本快排序出現(xiàn)的原因: 有時(shí),你會(huì)需要將多行記錄組合而成的數(shù)據(jù)排序。 地址清單就是一個(gè)很好的例子,為了方便閱讀,地址記錄經(jīng)常會(huì)切斷,以一個(gè)或數(shù)個(gè)空行批次隔開(kāi),像這種數(shù)據(jù),沒(méi)有一定的排序鍵值位置可供 -k
選項(xiàng)使用,所以就引入了文本快排序。
案例:
我有一個(gè)文件 adress.txt,內(nèi)容為:
J Luo
Southeast University
Nanjing,China
\
Y Zhang
Victory University
Melbourne,Australia
\
D Hou
Beijing University
Beijing,China
\
B Liu
Shanghai Jiaotong University
Shanghai,China
\
C Lin
University of Toronto
Toronto,Canada
要求:對(duì)文本塊根據(jù)學(xué)校的名字 (每個(gè)文本塊的第二行) 進(jìn)行排序,結(jié)果仍然能以文本塊的格式輸出。
awk '{a[$2]=$0}END{for(i=1;i<=asorti(a,b);i++)print a[b[i]]}' ORS='\n\n' RS= FS='\n' adress.txt
這一種方法效率高,各種牛逼,看不明白十格什么 JB 意思。
第二種方式:awk 'BEGIN{FS="\n";RS=""}{print $1":"$2":"$3":"}' adress.txt|sort -t ":" -k2|tr ":" "\n"
,這種方式貌似比較平民,適合屌絲玩家。 那到底是什么意思呢?
首先使用 awk
命令將文本塊轉(zhuǎn)化成以下這樣:
J Luo:Southeast University:Nanjing,China
Y Zhang:Victory University:Melbourne,Australia
D Hou:Beijing University:Beijing,China
B Liu:Shanghai Jiaotong University:Shanghai,China
C Lin:University of Toronto:Toronto,Canada
然后使用 sort
命令按照學(xué)校 (也就是原文本的第二行) 排序。 排序后的結(jié)果為:
D Hou:Beijing University:Beijing,China
B Liu:Shanghai Jiaotong University:Shanghai,China
J Luo:Southeast University:Nanjing,China
C Lin:University of Toronto:Toronto,Canada
Y Zhang:Victory University:Melbourne,Australia
最后使用 tr “:” “\n”
命令,將排序后的文本轉(zhuǎn)化回來(lái)。
awk
的 FS
: 輸入字段分隔符(缺省為space
),相當(dāng)于 -F
選項(xiàng)
awk -F ':' '{print}' shcool.txt
和 awk 'BEGIN{FS=":"}{print}' shcool.txt
是一樣的
RS:輸入記錄分隔符,缺省為 "\n"
缺省情況下,awk
把一行看作一個(gè)記錄;如果設(shè)置了 RS,那么 awk
按照RS
來(lái)分割記錄,此處的意思是說(shuō)將原文本看成是一條記錄。
例如,如果文件 c,cat c 為
hello world; I want to go swimming tomorrow;hiahia
運(yùn)行 awk 'BEGIN{RS =";"} {print}' c
的結(jié)果為
hello world
I want to go swimming tomorrow
hiahia
合理的使用 RS
和 FS
可以使得 awk
處理更多模式的文檔,例如可以一次處理多行,例如文檔 d ,cat d
的輸出為
1 2
3 4 5
\
6 7
8 9 10
11 12
\
hello
每個(gè)記錄使用空行分割,每個(gè)字段使用換行符分割,這樣的 awk
也很好寫(xiě)
awk 'BEGIN{FS ="\n"; RS =""} {print NF}' d
輸出
2
3
1
而 tr
的意思是替換,將":"
替換成"\n"
。