linux最常用awk数组总结
数组是 awk 的灵魂,处理文本中最不能少的就是它的数组处理。因为数组索引(下标)可以是数字和字符串,在 awk 中数组叫做关联数组 (associative arrays)。awk 中的数组不必提前声明,也不必声明大小。数组元素用 0 或空字符串来初始化,这是根据上下文而确定的。
一. 数组的定义
- 数字做数组索引(下标)
Array[1]="sun"
Array[2]="kai"
print Array[1]
print Array[2]
- 字符串做数组索引(下标)
Array["first"]="www"
Array["last"]="name"
Array["birth"]="1987"
print["birth"]
- 数组动态定义
# cat ips.txt
1.1.1.1, abc
1.1.1.1, ac
1.1.1.1, root
2.2.2.2, fd
2.2.2.2, s
3.3.3.3, as
3.3.3.3, dfe
# awk -F "[, ]+" '!array[$1]{print $1;array[$1]=10}{print $2}' ips.txt
1.1.1.1
abc
ac
root
2.2.2.2
fd
s
3.3.3.3
as
dfe
这里的!array[$1]{print $1;array[$1]=10}
表示动态定义数组,读取第一行时,array[$1]
的值为空,!array[$1]
的值为真,所以{print $1;array[$1]=10}
会执行。这里的array[$1]=10
这个赋值使得 array[$1]
有了值,所以读取第二行的时候!array[$1]
就为空了,所以{print $1;array[$1]=10}
就不会执行,所以只打印了一次ip。
二. 读取数组的值
- 用
for ... in
读取,读出的顺序不定。
# echo | awk '{ for(item in ENVIRON) print ENVIRON[item]; }'
- 根据下标顺序读取。length(array)是数组的长度
# awk { for(i=1;i<=length(array);i++) {print array[i]}; }
三. 数组相关函数
- length返回字符串以及数组长度,split进行分割字符串为数组,也会返回分割得到数组长度。
# awk 'BEGIN{info="it is a test";lens=split(info,arr," ");print length(arr),lens;}'
4 4
- asort对数组进行排序,返回数组长度。
# awk 'BEGIN{info="it is a test";split(info,arr," ");print asort(arr);}'
4
- 输出数组内容(无序输出)
# awk 'BEGIN{info="it is a test";split(info,arr," ");for(k in arr){print k,arr[k];}}'
4 test
1 it
2 is
3 a
for ... in
输出, 因为数组是关联数组,默认是无序的。所以通过for…in得到是无序的数组。如果需要得到有序数组,需要通过下标获得。
- 输出数组内容(有序输出)
# awk 'BEGIN{info="it is a test";len=split(info,arr," ");for(k=1;k<=len;k++){print k,arr[k];}}' 1 it 2 is 3 a 4 test
注意:数组下标是从1开始,与C数组不一样。
四. 判断键值存在
- 错误的判断方法
awk 'BEGIN{
tB["a"]="a1";
tB["b"]="b1";
if(tB["c"]!="1"){
print "no found";};
for(k in tB){
print k,tB[k];
}
}'
no found
a a1
b b1
c
以上出现奇怪问题,tB["c"]
没有定义,但是循环时候,发现已经存在该键值,它的值为空,这里需要注意,awk数组是关联数组,只要通过数组引用它的key,就会自动创建该序列。
- 正确判断方法
awk 'BEGIN{
tB["a"]="a1";
tB["b"]="b1";
if( "c" in tB){
print "ok";
};
for(k in tB){
print k,tB[k];
}
}'
a a1
b b1
if(key in array)
通过这种方法判断数组中是否包含key键值。
五. 删除键值
awk 'BEGIN{
tB["a"]="a1";
tB["b"]="b1";
delete tB["a"];
for(k in tB){
print k,tB[k];
}
}'
b b1
delete array[key]
可以删除,对应数组key的序列值。
六. 二维多维数组
awk的多维数组在本质上是一维数组,更确切一点,awk在存储上并不支持多维数组。awk提供了逻辑上模拟二维数组的访问方式。例如,array[2,4]=1
这样的访问是允许的。awk使用了一个特殊的字符串作为分割字段。
类似一维数组的成员测试,多维数组可以使用if ( (i,j) in array)
这样的语法,但是下标必须放置在圆括号中。可以通过array[k,k2]
引用获得数组内容。
awk 'BEGIN{
for(i=1;i<=9;i++)
{
for(j=1;j<=9;j++)
{
tarr[i,j]=i*j;
print i,"*",j,"=",tarr[i,j];
}
}
}'