awk里面的数组很好用

今天用awk数组处理了文本格式化得一个需求。原始文本是如下所示100W+行数据:

0x15a00000 0x6be00000 10 STREET_INDEX_10
0xe200000 0x6ca00000 10 STREET_INDEX_10
0x16e00000 0x6e200000 10 STREET_INDEX_10
0x478e0000 0x467e0000 14 ROAD_ELEMENT_INFO_0_13
0x47920000 0x467e0000 14 ROAD_ELEMENT_INFO_0_13
0x38ee0000 0x4bfe0000 14 ROAD_ELEMENT_INFO_0_13
0x38ee0000 0x4c020000 14 ROAD_ELEMENT_INFO_0_13
0x38ea0000 0x4c060000 14 ROAD_ELEMENT_INFO_0_13
0x3b3a0000 0x4c060000 14 ROAD_ELEMENT_INFO_0_13
0x34a00000 0x59600000 10 POI_CATEGORY_INDEX_10 POI_INDEX_10
0x3aa00000 0x59600000 10 POI_CATEGORY_INDEX_10 STREET_INDEX_10 POI_INDEX_10
0x3be00000 0x59600000 10 POI_CATEGORY_INDEX_10 POI_INDEX_10
0x40e00000 0x59600000 10 POI_CATEGORY_INDEX_10 STREET_INDEX_10 POI_INDEX_10

处理过后,得出不重复得最后文字描述字段。输出结果如下:

POI_INDEX_10
POI_CATEGORY_INDEX_10
ROAD_ELEMENT_INFO_0_13
CITY_INDEX_0
POI_14
STREET_INDEX_10
假设原始数据存放在文件data.txt, 那么shell为:

cat data.txt | cut -d " " -f 4- | awk -F " " '{for(i=1;i<=NF;i++) name[$i]++}END{for (idx in name) print idx}'

cut -d " " -f 4- : 取出从第四个域到最后得字段。

awk部分可注意下for循环格式。数组name[]其实是个hash表,键值$i对应得value默认初始为0. idx in name这里和python中得 for ...in...结构类似idx其实是name[]得key值。

awk得基本格式为:
awk [opion] 'BEGIN{action}pattern_1{action}pattern_2{action}END{action}' input_file1 [input_file2 ...]

也可换行:
awk [opion] 'BEGIN{action}
pattern_1{action}
pattern_2{action}
END{action}' input_file1 [input_file2 ...]

更具体得描述可参考下载到本地得网页。

下面是别处copy来得一个嵌套得循环:

awk '{a[ARGIND" "$1]=$2 # ARGIND是当前命令行文件的位置(从0开始),将它和第一列的value作为下标,建立数组a。
       b[$1]   #将第一列的value作为下标,建立数组b,目的是在读完所有文件之后,能得到第一列value的uniqe-list。
        }
END{ 
        for(i in b) { 
                printf i" " 
                for(j=1;j<=ARGIND;j++) printf "%s ", a[j" "i]?a[j" "i]:"-" #此时的ARGIND值为3.
print "" 
                }
        }' file1 file2 file3

上面片段来自:http://bbs.chinaunix.net/thread-2312439-1-1.html



你可能感兴趣的:(Linux)