Reputation: 43
sed '1d'|awk 'BEGIN{FS=";";sum=0} {sum+=$3; avg=sum/NR; if($3<avg) print $3}'
This is the unix command I tried for printing the salary of employees having salary less than the average salary of all the employees. The Input given was:
Empid;Empname;Salary
101;V;30000
102;A;45000
103;I;15000
104;S;40000
According to the input the average salary= 32500 which means 30000, 15000 both should be displayed in the output. But I can only get 15000 as my output. Please help and tell where am i going wrong.
Upvotes: 4
Views: 82
Reputation: 5965
awk -F";" 'NR>1 {sum += s[++i] = $3}
END {avg=sum/length(s); for (i=1;i in s;i++) if (s[i]<avg) print s[i]}' file
30000
15000
Also, no need to use both sed
and awk
for this. With awk
you store all salaries, and at the END
section you compare them with the average.
Upvotes: 4
Reputation: 133428
Could you please try following, written and tested based on shown samples. Change <=
to <
in case you want to get results only for lesser than average here.
awk '
BEGIN{
FS=OFS=";"
}
FNR==NR{
sum+=$NF
count++
next
}
FNR==1{
avg=sum/(count-1)
}
$NF<=avg
' Input_file Input_file
Explanation: Adding detailed explanation for above.
awk ' ##Starting awk program from here.
BEGIN{ ##Starting BEGIN section of this program from here.
FS=OFS=";" ##Setting field separator and output field separator as ; here.
}
FNR==NR{ ##Checking condition if FNR==NR which will be TRUE when first time Input_file is being read.
sum+=$NF ##Creating sum which is having last field value keep adding to it.
count++ ##Increasing count with 1 here.
next ##next will skip all further statements from here.
}
FNR==1{ ##Checking condition if FNR is 1 the do following.
avg=sum/(count-1) ##Creating avg which has division of sum and count-1 here.
}
$NF<=avg ##Checking condition if last field is lesser than or equal to avg then print that line.
' Input_file Input_file ##Mentioning Input_file names here.
Upvotes: 3