68

In my understanding, awk array is something like python dict.

So I write down the code bellow to explore it:

awk '{my_dict[$1] = $2} END { print my_dict}' zen

And I got: awk: can't read value of my_dict; it's an array name.

As the first column isn`t a number, how could I read the total content of the array or traverse it?

Zen
  • 7,537

4 Answers4

94

You can loop over the array's keys and extract the corresponding values:

awk '{my_dict[$1] = $2} END { for (key in my_dict) { print my_dict[key] } }' zen

To get output similar to that you'd get with a Python dictionary, you can print the key as well:

awk '{my_dict[$1] = $2} END { for (key in my_dict) { print key ": " my_dict[key] } }' zen

This works regardless of the key type.

Stephen Kitt
  • 434,908
23

That would loop through the array:

END { for (i in my_dict) print my_dict[i] }

i is the index.

chaos
  • 48,171
13

Array in awk is not first class object like dictionary in Python. In awk, array name without subscript can only use in two context:

  • A parameter in a function definition or function call.
  • Name token after keyword in.

In other context, awk will raise an error.

You need a for loop to iterate and print content of an array:

$ echo 1 2 | awk '{my_dict[$1] = $2};END {for(i in my_dict) print my_dict[i]}'
2
cuonglm
  • 153,898
4

GNU AWK uses multidimensional associative arrays such as:

family[me][father][grandpa][name]="George"
family[me][father][grandpa][age]=70
family[me][father][grandma][name]="Katherine"
family[me][father][name]="Vasiliy"
family[me][name]="Ivan"

etc.

Sometimes it's hard to explore awk arrays such as PROCINFO (because in addition to scalars it has also subarrays: argv & identifiers)

So I wrote this awk script for myself. Maybe it will be useful for you. You can remove such substrings: \033[1;31m if you don't like/have colored output.

#!/usr/bin/gawk -f
function arraytree(inputarray,arrname,i,member,arrnum){
 if(!isarray(inputarray)){
  print indent arrname member "[\033[1;31m" i "\033[0m]=\"\033[1;32m" inputarray"\033[0m\""
 }else{
  arrnum=i
  member=i?member "[" i "]":""
  print indent (i? arrname member:arrname)"(\033[1;34m" length(inputarray) " member"(length(inputarray)>1?"s":"")"\033[0m)"
  indent=indent " "
  for(i in inputarray){
   arraytree(inputarray[i],arrname,i,member,arrnum)}
   indent=substr(indent,1,length(indent)-1)
  }
}
BEGIN{
arraytree(ArrayName,"ArrayName")
}
Evgeny
  • 96