awk中的數組


awk中的數組
20130110

awk作為一門腳本語言,支持的數據類型主要是簡單變量和數組變量。awk中的數組與傳統的C和java中的數組不同,更類似於C++ STL中的map或python中的dict,是關聯式數組,通過關聯關系將key和value結合起來。並且它並不限制key和value的類型,可以在一個數組中混合使用多種類型的key和value(盡管可能不常這么用)。awk中的變量在使用之前是不需要聲明的,在第一次使用時確定它的類型,並且以后不再改變。所以如果一個變量arr第一次被當做數組來使用,那么以后就不能在用作簡單變量。假定arrary是一個數組變量,如果key不在array中,那么arrary[key]將返回一個空串;如果key在array中,則返回對應的變量arrary[key]。awk可以通過關鍵字in來判斷key是否在數組中出現。並且可以通過for(key in array)的形式來遍歷數組中的元素.

awk中數組的排序問題

awk中的數組是關聯式的,因此在使用for(key in array)的方式進行遍歷的時候,輸出的順序並不是按照key進行排序輸出的,因為awk中的數組內部采用hash的方式實現,因此輸出的順序能是不確定的。當需要按照某種順序輸出元素時,需要使用到asort和asorti函數來輔助。

asort的原型為:
asort(array1[, arrary[2]])
asort是將數組的value值進行排序,並且返回數組中元素的個數。如果采用asort(array)這種簡略方式,那么重排之后的數據將會保存在array中,但是關聯關系將會被取消,下面是一個簡單的例子:
[c-sharp] view plaincopy
"wang" => 15 1 => 33
"lim" => 14 2 => 19
"zhuang"=> 19 asort() -> 3 => 15
"han" => 334 4 => 14
"feng" => 11 5 => 11
排序結束之后,原先的關聯關系被取消,取而代之的是index與value的對應關系。

如果需要對key進行排序,那么可以使用asorti函數,該函數的原型為:
asorti(array1[, array2])
asorti將數組的key值進行排序,並返回數組中元素的個數。與asort類似,如果使用asorti(array)這種簡略的方式,那么排序后的key值成為value值,原先的關聯關系被破壞。下面是一個簡單的例子:
[c-sharp] view plaincopy
"wang" => 15 1 => feng
"lim" => 14 2 => han
"zhuang"=> 19 asort() -> 3 => lim
"han" => 33 4 => wang
"feng" => 11 5 => zhuang

如過想要保留原先的關聯關系,則可以使用asorti(array1, array2)這種形式,排序后的key被保存在array2數組中。
假定有如下的問題:有一個文件包含了一組人員的信息,格式的類型為:
[cpp] view plaincopy
Name Age Height Weight
wanger 18 173 74
liusan 20 177 80
zhaojun 24 167 49
tianjing 30 179 75
haobo 28 171 65
我們想要按照其中的某一項(比如身高)進行排序,當然是用sort工具就可以實現,現在我們使用awk來實現。下面是按照身高對所有的條目進行排序的代碼:
[cpp] view plaincopy
{
arrary[$2] = $0
}
END{
asorti(arrary, height);
for(h in height)
{
print arrary[height[h]];
}
}

awk中hash

需求:
2個文件列表a[n],b[n]。分別打出兩個文件不同的行,保存在不同的文件里

方法1:讀入a的每一行,分別到b[n]中grep。思路簡單,但效率低到抓狂
方法2:comm ,不清楚原理是什么,但效率也很低。。。
方法3:awk+hash(冒泡算法吧?)

  以找出只在a[n]中存在的行為例:設一個外層循環,分別取a[n]中的每一個文件$file_a;設一個內循環,使$file_a與每一個b[n]文件$file_b比較.每一次將$file_a中存在,$file_b中不存在的行賦給$tmp,再用$tmp代替$file_a在下一個$file_b中搜索,所以隨着過濾過的$file_b越多,$tmp中的行將越來越少,所有$file_b過濾后,就保證了$file_a中的所有與$file_b中相同的行已被過濾。

  唉,實際應用和學校里編程就是不一樣:學校里能實現的算法就是好算法;實際上還要考慮效率問題。在大數據量的應用中,我第一版的程序能跑上1個星期,優化到第三版時才能幾個小時搞定。

for file_a in a[n]
do
cp $file_a tmp
for file_b in b[n]
do
awk '
BEGIN{file=0;}
FNR1{file++;}
file
1{hash[$0]=1;}
file2{if($0 in hash)hash[$0]=0;}
END{for(key in hash)
{if(hash[key]
1)print key;}}
' $tmp $file_b >new_in_a
mv $new_in_a $tmp
done
cat $tmp >>$final_result
done


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM