Beth 45 0
Danny 33 0
Thomas 22 40
Mark 65 100
Mary 29 121
Susie 39 76.5
Joey 51 189.52
Peter 23 78.26
Maximus 34 289.71
Rebecca 21 45.79
Sophie 26 28.44
Barbara 24 107.36
Elizabeth 35 105.69
Peach 40 102.69
Lily 41 123
上面是一个数据文件,有三个字段:姓名、年龄、薪水。
我想打印 30 岁以上和 30 岁以下人员的平均工资、数字和姓名。
在本练习中,我想练习使用字符串作为下标。
这是我的 AWK 代码:
BEGIN { OFS = "\t\t" }
{
if ($2 < 30)
{
a = "age below 30";
salary[a] += $NF;
count[a]++;
name[a] = name[a] $1 "\t";
}
else
{
a = "age equals or above 30";
salary[a] += $NF;
count[a]++;
name[a] = name[a] $1 "\t";
}
}
END {
for (a in salary)
for (a in count)
for (a in name)
{
print "The average salary of " a " is " salary[a] / count[a];
print "There are " count[a] " people " a ;
print "Their names are " name[a];
print "********************************************************";
}
}
以下是输出:
The average salary of age equals or above 30 is 109.679
There are 9 people age equals or above 30
Their names are Beth Danny Mark Susie Joey Maximus Elizabeth Peach Lily
********************************************************
The average salary of age below 30 is 70.1417
There are 6 people age below 30
Their names are Thomas Mary Peter Rebecca Barbara Sophie
********************************************************
The average salary of age equals or above 30 is 109.679
There are 9 people age equals or above 30
Their names are Beth Danny Mark Susie Joey Maximus Elizabeth Peach Lily
********************************************************
The average salary of age below 30 is 70.1417
There are 6 people age below 30
Their names are Thomas Mary Peter Rebecca Barbara Sophie
********************************************************
The average salary of age equals or above 30 is 109.679
There are 9 people age equals or above 30
Their names are Beth Danny Mark Susie Joey Maximus Elizabeth Peach Lily
********************************************************
The average salary of age below 30 is 70.1417
There are 6 people age below 30
Their names are Thomas Mary Peter Rebecca Barbara Sophie
********************************************************
The average salary of age equals or above 30 is 109.679
There are 9 people age equals or above 30
Their names are Beth Danny Mark Susie Joey Maximus Elizabeth Peach Lily
********************************************************
The average salary of age below 30 is 70.1417
There are 6 people age below 30
Their names are Thomas Mary Peter Rebecca Barbara Sophie
********************************************************
输出对我来说很难理解。
我预期的应该是这样的:
The average salary of age equals or above 30 is 109.679
There are 9 people age equals or above 30
Their names are Beth Danny Mark Susie Joey Maximus Elizabeth Peach Lily
********************************************************
The average salary of age equals or above 30 is 109.679
There are 9 people age equals or above 30
Their names are Thomas Mary Peter Rebecca Barbara Sophie
********************************************************
The average salary of age equals or above 30 is 109.679
There are 6 people age below 30
Their names are Beth Danny Mark Susie Joey Maximus Elizabeth Peach Lily
********************************************************
The average salary of age equals or above 30 is 109.679
There are 6 people age below 30
Their names are Thomas Mary Peter Rebecca Barbara Sophie
********************************************************
The average salary of age below 30 is 70.1417
There are 9 people age equals or above 30
Their names are Beth Danny Mark Susie Joey Maximus Elizabeth Peach Lily
********************************************************
The average salary of age below 30 is 70.1417
There are 9 people age equals or above 30
Their names are Thomas Mary Peter Rebecca Barbara Sophie
********************************************************
The average salary of age below 30 is 70.1417
There are 6 people age below 30
Their names are Beth Danny Mark Susie Joey Maximus Elizabeth Peach Lily
********************************************************
The average salary of age below 30 is 70.1417
There are 6 people age below 30
Their names are Thomas Mary Peter Rebecca Barbara Sophie
********************************************************
所以我的第一个问题是:我哪里理解错了?
我的第二个问题是: 其实我不需要那么多循环。我只需要
The average salary of age equals or above 30 is 109.679
There are 9 people age equals or above 30
Their names are Beth Danny Mark Susie Joey Maximus Elizabeth Peach Lily
********************************************************
The average salary of age equals or above 30 is 109.679
There are 9 people age equals or above 30
Their names are Thomas Mary Peter Rebecca Barbara Sophie
********************************************************
for(工资、计数、姓名中的a)
不起作用。有更好的办法吗?
最佳答案
for (x in salary)
for (y in count)
for (z in name)
print "foo"
说对于salary中的每个索引,循环遍历count中的每个索引,同时,对于count中的每个索引循环遍历name中的每个索引并每次打印“foo”
。因此,如果工资、计数和姓名各有 3 个条目,那么您将打印“foo”3*3*3 = 9 次。
它比代码中的更复杂,因为您使用相同的变量来保存嵌套循环的每个级别的每个数组的索引值:
for (a in salary)
for (a in count)
for (a in name)
所以我不确定 awk 会用它做什么 - 它甚至可能是未定义的行为。
由于所有 3 个数组都具有相同的索引,因此只需选择其中一个数组并循环其索引,然后您就可以使用同一索引访问所有 3 个数组。
$ cat tst.awk
{
bracket = "age " ($2 < 30 ? "under" : "equals or above") " 30"
names[bracket] = (bracket in names ? names[bracket] "\t" : "") $1
count[bracket]++
salary[bracket] += $NF
}
END {
for (bracket in names) {
print "The average salary of", bracket, "is", salary[bracket] / count[bracket]
print "There are", count[bracket], "people", bracket
print "Their names are", names[bracket]
print "********************************************************"
}
}
$ awk -f tst.awk file
The average salary of age equals or above 30 is 109.679
There are 9 people age equals or above 30
Their names are Beth Danny Mark Susie Joey Maximus Elizabeth Peach Lily
********************************************************
The average salary of age under 30 is 70.1417
There are 6 people age under 30
Their names are Thomas Mary Peter Rebecca Sophie Barbara
********************************************************
关于arrays - 如何使用AWK正确打印循环中的关联数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51682332/