0

I'm trying to do a very simple awk script exercise and cannot figure why it isn't working.

The awk script should be used to only display entries begining with 2012, so given the following input file:

  2009 Dec X 29.44
  2009 Dec Y 32.32
  2012 Jan X 321.11
  2012 Feb Y 1.99
  2012 Feb X 32.99
  2012 Mar X 11.45
  2010 Jan X 14.75
  2011 Feb Y 21.00
  2011 Mar X 7.77

The output should be as follows:

 % awk -f awkscriptfile inputfile
  Data for year 2012
  ==================
  Jan : 321.11
  Feb : 1.99
  Feb : 32.99
  Mar : 11.45
  ===================
  volume for 2012 is: 367.54
  4 records processed
  %

However, what I get is this:

% awk -f awkscriptfile inputfile
    Data for year 2012
    ==================================
     2009 Dec X 29.44
     2009 Dec Y 32.32
     2012 Jan X 321.11
    Jan  :  321.11
     2012 Feb Y 1.99
    Feb  :  1.99
     2012 Feb X 32.99
    Feb  :  32.99
     2012 Mar X 11.45
    Mar  :  11.45
     2010 Jan X 14.75
     2011 Feb Y 21.00
     2011 Mar X 7.77
    ==================================
    volume for 2012 is: $sum
    $count records processed
%

So the awk script is obviously printing out a lot more than it should, and for some reason the sum and count variables aren't being printed.

This is my code for the awk script:

BEGIN {
 print "Data for year 2012"
 print "=================================="
 count = 0
 sum = 0
}
$1 ~ /2012/ {
 print $2, " : ", $4
 count++
 sum += $4
}
END {
 print "=================================="
 print "volume for 2012 is: $sum"
 print "$count records processed"
}

From everything I'm looking at for reference, I see no reason why this code shouldn't work. Hopefully someone else can tell me what I'm doing wrong.

5
  • 3
    That exact input and that exact script are not doing that here. Are you sure that's the script you are using exactly? Because that looks a lot like the output you would get with a stray truth-y pattern or a debugging {print} action. Commented Oct 27, 2014 at 16:58
  • 3
    Also, you don't use $ on variables and they don't interpolate in strings. So those last two lines want to be print "volume for 2012 is : "sum and print count " records processed". Commented Oct 27, 2014 at 17:00
  • I actually had a comment at the top of the script begining with "//" instead of "#", and changing that seems to have fixed it. I thought both worked with shell scripts, but I guess not. And the variable fix you offered of course worked too. Thank you so much! Commented Oct 27, 2014 at 17:10
  • 2
    Awk is not the shell; they are two different things. They do share their comment syntax with each other as well as many other UNIX utilities, however. I'm trying to think of any programming language that mixes shell-style # comments with C++-style // comments, and none is springing to mind.. Commented Oct 27, 2014 at 17:11
  • 1
    And // does not work in bash either... possibly csh though I suppose. And yes, // is a regex that matches anything and as such will run a default action to print the line (though I'm surprised the rest of your comment didn't cause problems but I suppose awk just saw the words as blank variables or something. Commented Oct 27, 2014 at 17:14

2 Answers 2

3
awk -v y="2012" '$1==y{a[NR]=$2":"$4;s+=$4;c++}
    END{line="===================";
    printf "Data for year %s\n%s\n",y,line;
    for(i=1;i<=NR;i++)if(a[i])print a[i]
    printf "%s\nvolume for %s is: %.2f\n%d records processed\n", line, y, s, c}' file

with your data, it outputs:

Data for year 2012
===================
Jan:321.11
Feb:1.99
Feb:32.99
Mar:11.45
===================
volume for 2012 is: 367.54
4 records processed
Sign up to request clarification or add additional context in comments.

Comments

1

Here is modified version of your script

Input

akshay@Aix:/tmp$ cat infile
  2009 Dec X 29.44
  2009 Dec Y 32.32
  2012 Jan X 321.11
  2012 Feb Y 1.99
  2012 Feb X 32.99
  2012 Mar X 11.45
  2010 Jan X 14.75
  2011 Feb Y 21.00
  2011 Mar X 7.77

Script

akshay@Aix:/tmp$ cat stat_data.awk
BEGIN{

    if( ARGC < 2 || year=="")
    {
        error=1
        print "\n\t\tUsage   : awk -vyear=<year> -f script.awk <input file>"
        print "\t\tExample : awk -vyear=2012 -f script.awk test.txt\n"
        exit
    }

        print "Data for year "year
        print "=================================="

}
$1==year{
        print $2":"$4
        sum+=$4
        count++
}
END{
     if(!error)
     {
        print "=================================="
        print "volume for "year" is: "sum
        print count" records processed"
     }
}

How to execute ?

akshay@Aix:/tmp$ awk -vyear=2012 -f stat_data.awk  infile

Output

Data for year 2012
==================================
Jan:321.11
Feb:1.99
Feb:32.99
Mar:11.45
==================================
volume for 2012 is: 367.54
4 records processed

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.