已复制
全屏展示
复制代码

linux最常用awk数组总结


· 4 min read

数组是 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];
            }
        }
    }'
🔗

文章推荐