Linux AWK:用 5 个示例来解释 AWK 数组
awk 编程语言支持数组。数组是变量的扩展。数组是包含多个值的变量。与变量类似,数组也有名称。在某些编程语言中,必须声明数组,以便为数组分配内存。此外,数组索引通常是整数,如 array[1]、array[2] 等,
awk 关联数组
awk 只支持关联数组。关联数组与传统数组类似,只是它们使用字符串作为索引而不是数字。使用关联数组时,您可以通过使用数字字符串作为索引来模仿传统数组。
Syntax:
arrayname[string]=value
在上面的 awk 语法中:
- arrayname是数组的名称。
- string是数组的索引。
- value是分配给数组元素的任何值。
访问 AWK 数组的元素
如果要访问数组中的特定元素,可以通过它的索引进行访问——arrayname[index],它会为您提供在该索引中分配的值。
如果要访问所有数组元素,可以使用循环遍历数组的所有索引,如下所示。
Syntax:
for (var in arrayname)
actions
在上面的 awk 语法中:
- var是任何变量名
- in是一个关键字
- arrayname是数组的名称。
- 动作是要执行的语句列表。如果要执行多个操作,则必须将其括在大括号内。
此循环执行每个不同值的操作列表,这些值用作数组中的索引,变量 var 设置为该索引。
从 AWK 数组中删除一个元素
如果要删除数组特定索引中的元素,请使用 awk delete 语句。一旦从 awk 数组中删除了一个元素,就无法再获得该值。
Syntax:
delete arrayname[index];
下面的循环命令从数组中删除所有元素。没有一条语句可以从数组中删除所有元素。您必须遍历循环并使用 awk delete 语句删除每个数组元素。
for (var in array)
delete array[var]
5 个实用的 awk 数组示例
下面给出的所有示例都使用如下所示的 Iplogs.txt 文件。此示例文本文件包含网关服务器请求的 IP 地址列表。此示例 Iplogs.txt 文件包含以下格式的数据:
[date] [time] [ip-address] [number-of-websites-accessed]
$ cat Iplogs.txt
180607 093423 10.12.23.122 133
180607 121234 12.25.45.221 153
190607 084849 21.178.23.4 44
190607 084859 166.78.22.64 12
200607 012312 222.188.3.2 13
210607 084849 230.178.23.4 34
210607 121435 230.178.23.4 32
210607 132423 230.188.3.2 167
示例 1. 列出所有唯一的 IP 地址和被请求的次数
$ awk '{
> Ip[$3]++;
> }
> END{
> for (var in Ip)
> print var, "access", Ip[var]," times"
> }
> ' Iplogs.txt
125.25.45.221 access 1 times
123.12.23.122 access 1 times
164.78.22.64 access 1 times
202.188.3.2 access 2 times
202.178.23.4 access 3 times
在上面的脚本中:
- 第三个字段 ($3) 是一个 IP 地址。这用作称为 Ip 的数组的索引。
- 对于每一行,它都会增加相应 ip 地址索引的值。
- 最后在 END 部分,所有索引将是唯一 IP 地址的列表,其对应的值是出现次数。
示例 2. 列出所有 IP 地址并计算它访问了多少个站点
Iplogs.txt 中的最后一个字段是每个 IP 地址在特定日期和时间访问的站点数。下面的脚本生成报告,其中包含 IP 地址列表以及它请求网关的次数以及它访问的站点总数。
$cat ex2.awk
BEGIN {
print "IP Address\tAccess Count\tNumber of sites";
}
{
Ip[$3]++;
count[$3]+=$NF;
}
END{
for (var in Ip)
print var,"\t",Ip[var],"\t\t",count[var];
}
$ awk -f ex2.awk Iplogs.txt
IP Address Access Count Number of sites
125.25.45.221 1 153
123.12.23.122 1 133
164.78.22.64 1 12
202.188.3.2 2 180
202.178.23.4 3 110
在上面的例子中:
- 它有两个数组。两个数组的索引相同——即 IP 地址(第三个字段)。
- 第一个名为“Ip”的数组包含唯一 IP 地址列表及其出现次数。第二个名为“count”的数组将 IP 地址作为索引,其值将是最后一个字段(站点数),因此每当 IP 地址出现时,它只会继续添加最后一个字段。
- 在 END 部分,它遍历所有 IP 地址,并从名为 Ip 的阵列打印 Ip 地址和访问计数,以及来自阵列计数的站点数。
示例 3. 确定最长访问日
$ cat ex3.awk
{
date[$1]++;
}
END{
for (count in date)
{
if ( max < date[count] ) {
max = date[count];
maxdate = count;
}
}
print "Maximum access is on", maxdate;
}
$ awk -f ex3.awk Iplogs.txt
Maximum access is on 210607
在这个例子中:
- 名为“date”的数组将日期作为索引,将出现次数作为数组的值。
- max 是一个具有计数值的变量,用于找出具有最大计数的日期。
- maxdate 是一个变量,它具有计数最大的日期。
示例 4. 反转文件中的行顺序
$ awk '{ a[i++] = $0 } END { for (j=i-1; j>=0;) print a[j--] }' iplogs.txt
210607 132423 202.188.3.2 167
210607 121435 202.178.23.4 32
210607 084849 202.178.23.4 34
200607 012312 202.188.3.2 13
190607 084859 164.78.22.64 12
190607 084849 202.178.23.4 44
180607 121234 125.25.45.221 153
180607 093423 123.12.23.122 133
在这个例子中,
- 它首先记录数组“a”中的所有行。
- 当程序处理完所有行后,Awk 执行 END { } 块。
- END 块循环遍历数组“a”中的元素并以相反的方式打印记录的行。
示例 5. 使用 awk 删除重复和不连续的行
$ cat > temp
foo
bar
foo
baz
bar
$ awk '!($0 in array) { array[$0]; print }' temp
foo
bar
baz
在这个例子中:
- awk 从文件“temp”中读取每一行,并使用“in”运算符检查当前行是否存在于数组“a”中。
- 如果不存在,则存储并打印当前行。
- 点赞
- 收藏
- 关注作者
评论(0)