我的表格文件示例如下
Name1 xxxxx 34
Name1 xxxxx 37
Name2 aaaaa 59
Name2 xxxxx 90
Name4 Name3 12
名称文件看起来像那样
Name1
Name2
Name3
Name4
我希望awk
与名称文件中的Name1/2/3/4
匹配到表格文件$ 1,并打印$ 3的总和。 如果找不到姓名打印 0
- 如何在if
中执行此类awk
声明?
我已经做了什么:
for i in $(cat Name_file)
do
cat table | awk -v NAME="$i" '($1==NAME) {SUM+=$3} END {print NAME"\t"SUM}'
done
提供输出
Name1 71
Name2 149
Name3
Name4 12
这几乎是完美的 - 我想将0
添加到Name3
以获得此类输出
Name1 71
Name2 149
Name3 0
Name4 12
这么多问题是:如何在awk中添加if not found do
函数?
答案 0 :(得分:2)
Y不需要任何“未找到”行为。在计数之前,您没有正确初始化SUM
变量。请使用BEGIN {SUM = 0}
。
如果您需要明确找到/未找到行为,请执行相似操作。首先,初始化一些变量BEGIN {FOUND = 0}
,然后在模式匹配上进行某种更改:(...) {FOUND = FOUND+1}
,最后使用if(FOUND!=0)
进行测试。
答案 1 :(得分:1)
尝试这样的sg:
awk 'NR==FNR{a[$1]=0;next}$1 in a{a[$1]+=$3}END{for(i in a) print i,a[i]}' Name_file table
输出:
Name1 71
Name2 149
Name3 0
Name4 12
在这种情况下,bash周围不需要awk循环。它首先读取Names_table
,然后一步处理table
的所有行。所以它更有效。
<强> ADDED 强>
或纯bash(&gt; = 4.0)解决方案:
printf -v tmp "[%s]=0 " $(<Name_file)
declare -A htmp
eval htmp=($tmp)
while read a b c; do [ -n "${htmp[$a]}" ] && ((htmp[$a] += $c)); done <table
for i in ${!htmp[*]}; do echo $i ${htmp[$i]}; done
<强>扩展强>
扩展的问题是按$1
和$2
分组(Name_file
包含来自table
的所有第一个键,因此不需要处理)。< / p>
cat >table <<XXX
Name1 xxxxx 34
Name1 xxxxx 37
Name2 aaaaa 59
Name2 xxxxx 90
Name4 Name3 12
XXX
awk -v SUBSEP=, '{a[$1,$2]+=$3;++n[$1,$2]}END{for(i in a) print i,a[i],n[i]}' table
输出:
Name2,xxxxx 90 1
Name2,aaaaa 59 1
Name4,Name3 12 1
Name1,xxxxx 71 2