awk技巧-!a[$0]++

轉載自:http://www.51testing.com/html/87/363787-811057.html

解釋下
awk '!a[$0]++' file

一看之下,首先是想到又用到awk的hash,又是缺省的pattern,一下子來了興趣,做了以下的分析

這個要從awk的執行模式開始說,最後結合++運算符,和hash特色
有三個基本知識點是要了解的
1:a++的作用是先附值,再累加a,與++a正好相反。

2:hash的初始是undef,通過直接附值或聲明進行定義,如a[1]=1,或直接聲明a[1]。

3:awk的基本模式是,pattern   { action statements },action部分是可以省略的,缺省情況下是輸出,即{print $0},至於pattern可以理解成是表達式,通過pattern表達式的值的真假,來確定是否要進行action。比如1,最簡單的awk用來實現cat的功能就是 awk '1',這邊1就是pattern,當然,1也可以是2,3,4,5等其他數字,但如果用字母的話,就不行,因爲字母會解釋成變量,變量初始值未定義,初始值爲假,或者可以加個!反義

結合上邊三點來分析awk '!a[$0]++' file
"!a[$0]++"

0:整個模式,沒有用到action,所以採用的是默認的{print $0},即在patten爲真條件來,輸出行
patten分析:
1:使用了一個hash數組,a,數組的鍵值採用$0,即每行值
2:當a[$0]未聲明時,a[$0]爲假,在未聲明的情況下,進行一次a[$0]++後,a[$0]即爲真
3:!取反
結論:當相同的行第一次讀入時,pattern爲真,行輸出,再次讀入後,patten爲假,行乎略

基本理論知道了,要用得出來還得多鍛鍊應用

上週幫別人寫個awk,也是這種情況
我寫的
awk '{if($2 in a);else{a[$2]=$0}}END{for(b in a)print a[b]}' urrfile

後來別人給出更簡單的答案
awk ' !($2 in i){ i[$2]; print } ' urrfile

現在看來,還可以更簡單些
awk '!a[$2]++' urrfile


【注意】:這是前加/後加的區別,前幾天還說過。


   後加: 先使用變量的值,再自加。

   !a[$0]++ 對這個表達式的求值,它的值與 !a[$0] 相同(先使用變量a[$0]的值),但對表達式求值後 a[$0]會自加。

發佈了27 篇原創文章 · 獲贊 3 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章