Awk instructions - if not found (grep'ed) do

An example of my table file looks like this:

Name1 xxxxx 34 Name1 xxxxx 37 Name2 aaaaa 59 Name2 xxxxx 90 Name4 Name3 12 

The name file looks like this:

 Name1 Name2 Name3 Name4 

I want awk match Name1/2/3/4 from the name file to the table file $ 1 and print the amount of $ 3. If the name is not found print 0 - how can I make such an if in awk ?

What I have already done:

 for i in $(cat Name_file) do cat table | awk -v NAME="$i" '($1==NAME) {SUM+=$3} END {print NAME"\t"SUM}' done 

Produces output

 Name1 71 Name2 149 Name3 Name4 12 

It's almost perfect - I want to add 0 to Name3 to get this output

 Name1 71 Name2 149 Name3 0 Name4 12 

So many questions: how to add if not found do function in awk?

+6
source share
2 answers

Try sg as follows:

 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 

Output:

 Name1 71 Name2 149 Name3 0 Name4 12 

In this case, you do not need the bash loop. First, it reads Names_table , then it processes all the table rows in one step. So it is much more effective.

ADDED

Or pure bash (> = 4.0):

 printf -v tmp "[%s]=0 " $(<Name_file) declare -A htmp eval htmp=($tmp) while read abc; do [ -n "${htmp[$a]}" ] && ((htmp[$a] += $c)); done <table for i in ${!htmp[*]}; do echo $i ${htmp[$i]}; done 

DISTRIBUTION

The extended question consisted of a grouping of $1 and $2 (and Name_file contains all the first keys from table , so this really does not need to be processed).

 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 

Output:

 Name2,xxxxx 90 1 Name2,aaaaa 59 1 Name4,Name3 12 1 Name1,xxxxx 71 2 
+1
source

Y does not need any "not found" behavior. You simply incorrectly initialized the SUM variable before counting. Use BEGIN {SUM = 0} for this.

If you need to explicitly find / not find behavior, do it the same way. Initialize some BEGIN {FOUND = 0} variable BEGIN {FOUND = 0} , then change it in some way to match the pattern: (...) {FOUND = FOUND+1} and finally check it with if(FOUND!=0) .

+2
source

Source: https://habr.com/ru/post/947201/


All Articles