Printing blank lines when looping associative array in AWK

Viewed 73

I am not clear why blank lines are being printed instead of their correct values from day[] array in AWK.

BEGIN{
        day[1]="Sunday"
        day["first"]="Sunday"
        day[2]="Monday"
        day["second"]="Monday"
        day[4]="Wednesday"
        day["fourth"]="Wednesday"
        day[3]="Tuesday"
        day["third"]="Tuesday"
        for (i in day)
        {
            print $i
            print day[$i]
        }
}

Explicity printing out individual array elements yield the expected values as follows:

 BEGIN{
        day[1]="Sunday"
        day["first"]="Sunday"
        day[2]="Monday"
        day["second"]="Monday"
        day[4]="Wednesday"
        day["fourth"]="Wednesday"
        day[3]="Tuesday"
        day["third"]="Tuesday"
        print day[1]
        print day["first"]
        print day[2]
        print day["second"]
        print day[3]
        print day["third"]
        print day[4]
        print day["fourth"]
}

I am running Linux fedora 5.12.11-300.

Many thanks in advance,

Mary

3 Answers

You shouldn't use $ while printing i or array value as it refers to value of field in awk language, use following instead. Also you need not to use 2 times print statements, you could use single print with newline in it too.

awk '
BEGIN{
        day[1]="Sunday"
        day["first"]="Sunday"
        day[2]="Monday"
        day["second"]="Monday"
        day[4]="Wednesday"
        day["fourth"]="Wednesday"
        day[3]="Tuesday"
        day["third"]="Tuesday"
        for (i in day)
        {
           print i ORS day[i]
        }
}'

Improved version of awk: Also you need to to use 2 statements for same value, you can define them in single assignment way. Even with different indexes having same values it should work, that will save few lines of code :)

awk '
BEGIN{
        day[1]=day["first"]="Sunday"
        day[2]=day["second"]="Monday"
        day[4]=day["fourth"]="Wednesday"
        day[3]=day["third"]="Tuesday"
        for (i in day)
        {
            print i OFS day[i]
        }
}'

A less verbose way of doing this is by splitting input strings, e.g.:

awk -v days='Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday' \
    -v cardinal='First,Second,Third,Fourth,Fifth,Sixth,Seventh' '
BEGIN { 
  split(days,     days_ar,     /,/)
  split(cardinal, cardinal_ar, /,/)
  for (i=1; i<=7; i++) 
    print cardinal_ar[i] " = " days_ar[i]
}' | column -t

Output:

First    =  Monday
Second   =  Tuesday
Third    =  Wednesday
Fourth   =  Thursday
Fifth    =  Friday
Sixth    =  Saturday
Seventh  =  Sunday

Thank you so much to all those who have contributed to answering my call for help.

I chose the first answer because I am interested finding out the cause of why the array values weren't being printed. RavinderSingh13 correctly identified the reason which was due to the use of $ with variable i. I have mistakenly treated Awk as shell scripting. Below is the code that printed the array values without including $ variable:

awk '
BEGIN{
        day[1]=day["first"]="Sunday"
        day[2]=day["second"]="Monday"
        day[3]=day["third"]="Tuesday"
        day[4]=day["fourth"]="Wednesday"
        for (i in day)
        {
            print i,day[i]
        }
}'

One interesting point that I have learnt from Awk scripting, is that only the BEGIN section would always run, with/without reading an input file(s). On the other hand, the body / END / both sections would not run unless the Awk statement is accompanied by at least an input file.

Related