Linux AWK:用 5 个示例来解释 AWK 数组

举报
Tiamo_T 发表于 2022/02/03 08:37:58 2022/02/03
【摘要】 awk 编程语言支持数组。数组是变量的扩展。数组是包含多个值的变量。与变量类似,数组也有名称。在某些编程语言中,必须声明数组,以便为​​数组分配内存。此外,数组索引通常是整数,如 array[1]、array[2] 等,

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”中。
  • 如果不存在,则存储并打印当前行。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。