≡菜单

AWK阵列介绍了5个实用示例

AWK编程语言支持数组。作为我们正在进行的一部分 awkexamples 系列,我们已经看到 awkuser defined 变种iablesawkbuilt-in 变种iables。数组是变量的扩展。数组是包含多个值的变量。与变量类似,数组也有名称。在某些编程语言中,必须声明数组,以便为​​数组分配内存。此外,数组索引通常是整数,例如array [1],array [2]等,

Awk关联数组

Awk仅支持关联数组。关联数组与传统数组类似,不同之处在于它们使用字符串作为索引而不是数字作为索引。使用关联数组时,可以通过使用数字字符串作为索引来模仿传统数组。

Syntax:

arrayname[string]=value

In the above awksyntax:

  • 数组名 是数组的名称。
  • 是数组的索引。
  • 是分配给数组元素的任何值。

访问AWK数组的元素

如果要访问数组中的特定元素,则可以通过其索引进行访问—arrayname [index],它为您提供在该索引中分配的值。

如果要访问所有数组元素,可以使用循环遍历数组的所有索引,如下所示。

Syntax:

for (var 在 数组名)
actions

In the above awksyntax:

  • 变种 是任何变量名
  • 是一个关键字
  • 数组名 是数组的名称。
  • 行动 是要执行的语句列表。如果要执行多个动作,则必须将其括在大括号内。

此循环针对每个不同的值执行动作列表,这些值用作变量var设置为该索引的数组中的索引。

从AWK阵列中删除元素

如果要删除数组特定索引中的元素,请使用awk delete语句。从awk数组中删除元素后,就无法再获取该值。

Syntax:

delete 数组名[index];

下面的loop命令从数组中删除所有元素。没有单个语句可以删除数组中的所有元素。您必须遍历循环并使用awk delete语句删除每个数组元素。

for (var 在 array)
     delete array[var]

5个实用的Awk阵列示例

下面给出的所有示例都使用下面显示的Iplogs.txt文件。此示例文本文件包含网关服务器请求的IP地址列表。此示例Iplogs.txt文件包含以下格式的数据:

[date] [time] [ip-address] [number-of-websites-accessed]
$ cat Iplogs.txt
180607 093423	123.12.23.122 133
180607 121234	125.25.45.221 153
190607 084849   202.178.23.4 44
190607 084859   164.78.22.64 12
200607 012312202.188.3.2 13
210607 084849 202.178.23.4 34
210607 121435202.178.23.4 32
210607 132423202.188.3.2 167

Example 1. List all unique IP addresses 和 number of 次 it was requested

$ awk'{
> Ip[$3]++;
> }
> END{
> for (var 在 Ip)
> print 变种,"访问", Ip[var]," 次"
> }
> ' Iplogs.txt
125.25.45.221 访问 1  次
123.12.23.122 访问 1  次
164.78.22.64 访问 1  次
202.188.3.2 访问 2  次
202.178.23.4 访问 3  次

在上面的脚本中:

  • 第三个字段($ 3)是一个IP地址。这用作称为Ip的数组的索引。
  • 对于每一行,它都会增加相应IP地址索引的值。
  • Finally 在 the END section, all the 在dex will be the list of unique IP address 和 its corresponding 值s are the occurrence 计数.

Example 2. List all the IP address 和 calculate how many sites it 访问ed

Iplogs.txt中的最后一个字段是每个IP地址在特定日期和时间访问的站点数。以下脚本将生成报告,其中包含IP地址列表,请求网关的次数以及访问的站点总数。

$cat ex2.awk
BEGIN {
print "IP Address\tAccess Count\tNumber of sites";
}
{
Ip[$3]++;
count[$3]+=$NF;
}
END{
for (var 在 Ip)
	print 变种,"\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地址,它就一直添加最后一个字段。
  • In the END section, it goes through all the IP address 和 prints the Ip address 和 访问 计数 from the array called Ip 和 number of sites from the array 计数.

Example 3. Identify maximum 访问 day

$ cat ex3.awk
{
date[$1]++;
}
END{
for (count 在 日期)
{
	if ( 最高< 日期[count] ) {
		max = 日期[count];
		maxdate = 计数;
	}

}
print "Maximum 访问 is 上 ", maxdate;
}

$ awk-f ex3.awk Iplogs.txt
Maximum 访问 is 上  210607

在此示例中:

  • 命名数组“date” has 日期 as an 在dex 和 occurrence 计数 as the 值 of the array.
  • 最高is a 变种iable which has the 计数 值 和 used to find out the 日期 which has 最高计数.
  • maxdate is a 变种iable which has the 日期 for which the 计数 is maximum.

例子4.反转文件中的行顺序

$ awk'{ a[i++] = $0 } END { for (j=i-1; j>=0;) print a[j--] }' Iplogs.txt
210607 132423202.188.3.2 167
210607 121435202.178.23.4 32
210607 084849 202.178.23.4 34
200607 012312202.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 > 温度
foo
bar
foo
baz
bar

$ awk'!($0 在 array) { array[$0]; print }' 温度
foo
bar
baz

在此示例中:

  • AWK从文件中读取每一行“temp”, 和 using “in”操作符,它检查当前行是否存在于数组中“a”.
  • 如果不存在,它将存储并打印当前行。

推荐读物

Sed和Awk 101骇客,作者:Ramesh Natarajan。我每天在UNIX / Linux环境上花费数小时来处理文本文件(数据,配置和日志文件)。我所有的文本处理工作都使用Sed和Awk。根据我在Sed和Awk的经验,’编写了Sed和Awk 101 Hacks电子书,其中包含有关Sed和Awk各种高级功能的101个实用示例,这些示例将延长UNIX / Linux的寿命。即使您已经使用Sed和Awk已有数年并且没有读过这本书,也请帮个忙并阅读这本书。 Sed和Awk实用程序的功能会让您惊讶。

如果您喜欢这篇文章,您可能还会喜欢..

  1. 50个Linux Sysadmin教程
  2. 50个最常用的Linux命令(包括示例)
  3. 排名前25位的最佳Linux性能监视和调试工具
  4. 妈妈,我找到了! – 15个实用的Linux Find命令示例
  5. Linux 101 Hacks第二版电子书 Linux 101黑客手册

Bash 101 Hacks书 Sed和Awk 101黑客手册 Nagios Core 3书 Vim 101黑客手册

{ 15 评论… add 一 }

  • 阿尔多姆 2010年3月10日,上午2:46

    很肠…
    多数组示例:

    #!/ bin / bash
    矩阵=(“one” “two” “three”)
    一=(“1.1” “1.2” “1.3”)
    二=(“2.1” “2.2” “2.3”)
    三=(“3.1” “3.2” “3.3” )

    为我在$ {Matrix [@]}中

    一_Item = $(评估回声“\${$i[0]}”)
    二_Item = $(评估回声“\${$i[1]}”)
    三_Item = $(评估回声“\${$i[2]}”)
    完成

  • 埃里克·普尔维诺 2010年3月10日,上午8:53

    在这里看几个这样的例子,我将把这些数组更多地称为MAPS。我的想法是,在awk情况下,索引不一定在数值上连续…。它们更像是C ++样式映射中使用的键,可以根据需要采用任何值以适合数据集。

    虽然有趣的功能,但我一定会在某些时候使用它’m sure.

  • Porosec 2010年6月6日,上午1:30

    我认为解决示例3更有效

    awk‘max < $1 { 最高= $1 } END { print 最高}' Iplogs.txt

  • jagadeeshwaran k 2012年6月11日,上午7:20

    非常有意思 。我已经学到了很多关于awk中数组的东西。

  • 凯奇 2012年6月28日,上午12:30

    ..i需要更多数组示例!

  • ana 2012年8月10日,上午1:25

    suer super super !!!!!!!!

  • 艾西瓦娅 2013年4月30日,上午2:26

    示例4的另一种方法。反转文件中的行顺序
    awk‘BEGIN{s=””} {s=$0″\n”s;} END{printf(“%s”,s);}’ Iplogs.txt

  • 一月 2013年6月11日,上午7:36

    请帮忙。我需要添加” 0|” before “QESTMD”或所有第四个细分–我该如何使用awk?

    数据:

    0 || 08276101 | QESTMD || 10 | 1 | 257.05 | 787736015 | 7877360B | 10062013 | 0 | DISP |||
    0 || 08276101 | QESTMD || 10 | 2 | 85.86 | 744549019 | 7445490B | 10062013 | 0 | DISP |||
    0 || 08276401 | PHARMD || 100 | 1 | 7.49 | 894672004 | 8946720E | 10062013 | 0 | DISP |||
    0 || 08276402 | TRANNS || 20 | 0 | 0 | 759694001 | 7596940B | 10062013 | 0 | DISP |||

    输出应为:

    0 || 08276101 | 0 | QESTMD || 10 | 1 | 257.05 | 787736015 | 7877360B | 10062013 | 0 | DISP |||
    0 || 08276101 | 0 | QESTMD || 10 | 2 | 85.86 | 744549019 | 7445490B | 10062013 | 0 | DISP |||
    0 || 08276401 | 0 | PHARMD || 100 | 1 | 7.49 | 894672004 | 8946720E | 10062013 | 0 | DISP |||
    0 || 08276402 | 0 | TRANNS || 20 | 0 | 0 | 759694001 | 7596940B | 10062013 | 0 | DISP |||

  • 曼尼什 2013年7月30日,上午1:19

    a1是包含问题数据的文件。
    awk‘BEGIN {FS = “|”;OFS=”|” }; {TT=”0|”$4;$4=TT;print $0}’ a1

  • 昌迪加聊天 2014年4月23日,下午3:33

    如何将目录中所有文件的所有者拆分为一个数组并显示第一个所有者?我使用的代码是:

    ls -ltr | awk‘{ x=split($3,a,” “); print x[0];}’

    但这会带来错误。请帮忙!

    谢谢
    〜C

  • 拉滕德拉·潘迪 2016年4月28日,下午12:02

    在gawk中使用数组的重要技巧。谢谢。

  • 拉滕德拉·潘迪 2016年4月28日,下午12:27

    是否有直接的方法来查找特定IP的访问次数?我试过了,但是没有用:

    awk‘{ Ip[$3]++; } END{ print 变种,“access”, Ip[202.188.3.2],” 次” }’

  • 保罗·佩丹 2016年5月27日,上午9:48

    拉滕德拉

    首先,var是print语句中的未定义变量。

    其次,202.188.3.2是无效常数。它有太多的点不能用作浮点数nimner,也没有引号使它成为字符串。

    awk将为您提供足够的诊断信息来帮助您解决此问题,但无论如何,您都应该发布看到的错误消息,而不仅仅是“it did not work”.

  • 拉滕德拉·潘迪 2016年12月7日,下午6:39

    嗨,Paul_Pedant,
    谢谢回答。去除点后即可打印‘.’从上面的IP地址:

    plxc25800> cat ~/Iplogs2.txt
    180607 093423 123 133
    180607 121234 125221 153
    190607 084849 2024 44
    190607 084859 16464 12
    200607 012312 2022 13
    210607 084849 2024 34
    210607 121435 2024 32
    210607 132423 2022 167

    plxc25800> awk‘{ Ip[$3]++; } END{ print 变种,“access”, Ip[2022], “times”}’ ~/Iplogs2.txt
    访问 2 次

  • 保罗·佩丹 一月20,2017,7:12上午

    拉内德拉
    您可能想再次阅读我以前的文章。

    (1)您还没有从样本数据中删除点。

    投入(在主要职位第5项中)为:
    200607 012312202.188.3.2 13
    210607 084849 202.178.23.4 34
    210607 121435202.178.23.4 32
    210607 132423202.188.3.2 167

    您的输入(显示在上面的最后一篇文章中)是:
    200607 012312 2022 13
    210607 084849 2024 34
    210607 121435 2024 32
    210607 132423 2022 167

    因此,实际上您已经省略了两个IP4地址字节来完成此工作。那’s made them non-unique anyway, so you are now 计数ing the wrong thing.

    (2)您仍在使用“var, “。 Var是未定义的变量—在代码中没有其他地方。发生awk将该情况视为空值(空),但是它’反正这样做是很糟糕的做法。

    (3)您的问题不是点,而是引号。

    您的代码应将IP地址设置为字符串,然后它将对原始数据起作用。

    由于您提供的IP地址不带引号,因此awk会尝试将文本内容作为变量名,将数字内容作为整数或浮点数,并将其他任何形式表示为表达式,这将使它窒息,或者发生意外情况。

    测试一下:

    awk”’
    开始{“202.188.3.2”; }
    {Ip [$ 3] ++; }
    END {打印“访问”,Ip [Key],“ times”}
    ”’ ~/Iplogs.txt

发表评论