2

I have a list a variables being used in an awk command. They are passed parameters for a script so their value is undetermined but I am trying to use them in a for loop.

My question is can I use the value of a variable as part of another variables name? Or is this a bad idea and if so is there another route I can take?

Example

awk -v var1=hi -v var2=howdy -v var3=greetings \
'BEGIN{for (i = 1; i <= 3; ++i) print var+i}'

Desired Output

hi
howdy
greetings
Gray_M
  • 31
  • 1
  • 5
  • Notice that + does not concatenate strings in awk as it does in javascript and other languages. In awk, you simply write them next to one another (which has lower precedence than <, >, etc and higher than +, -, etc): a="foo"; b="bar"; print a b => foobar. –  Oct 30 '19 at 16:01
  • If your problem is just how to pass some arguments to your awk script, then get them from ARGV and replace them with an empty string; that will cause awk to skip them when processing the command line args as file names: awk 'BEGIN{ for(i=1; i<=3; i++) { a[i] = ARGV[i]; ARGV[i] = "" } } {print}' hi howdy greetings /the/first/file/path –  Oct 30 '19 at 16:25
  • This sounds a lot like an YX Question. See https://meta.stackexchange.com/q/66377/361691. – Ed Morton Oct 31 '19 at 03:44

2 Answers2

3

I don't think that's possible in awk proper.

GNU awk (gawk) however has since version 4.1.0 (May 2013) a SYMTAB array whose keys are the names of all global variables, so:

gawk -v var1=hi -v var2=howdy -v var3=greetings '
  BEGIN { for (i=1; i<=3; i++) print SYMTAB["var"i] }
'
hi
howdy
greetings
  • This code standalone doesn't work for me, I am using GNU bash and gawk. My initial idea was to use a["var"i] arrays but populating it seemed like the wrong way to go about that. How different is SYMTAB[] from a[]? – Gray_M Oct 30 '19 at 17:37
  • You're probably using some older (<4.1.0) version of gawk. I've added some compat info to the answer. Depending on what you're trying to achieve, using (awk's fake) multidimensional arrays may help realize something resembling references. (look into the manpage for SUBSEP). GNU awk also has real multidimensional arrays, but they're probably a "new" feature, too. –  Oct 30 '19 at 18:08
  • I am using GNU bash, version 4.2.4. I don't believe version is the issue – Gray_M Oct 30 '19 at 18:11
  • It's not the bash's version which matters, but the gawk's. What does gawk --version say? –  Oct 30 '19 at 18:12
  • 1
    true multi-dimensional arrays (arrays of arrays) are supported in gawk since version 4.0.0 (June 2011). –  Oct 30 '19 at 18:38
1

Pass your values as a single string, then split that string and iterate over its parts:

awk -v delim=":" -v string='hi:howdy:greetings' '
    BEGIN {
        n = split(string, a, delim)
        for (i = 1; i <= n; ++i)
            print a[i]
    }'

The above code takes the string together with a variable, delim, that specifies what delimiter is being used in the string. This would work with any implementation of awk.

If you have separate variables in your shell script that you want to pass like this, for example the list of positional parameters:

#!/bin/sh

IFS=:
awk -v delim="$IFS" -v string="$*" '
    BEGIN {
        n = split(string, a, delim)
        for (i = 1; i <= n; ++i)
            print a[i]
    }'

Testing:

$ ./script.sh 1 2 3 "hello world"
1
2
3
hello world

See also:

Kusalananda
  • 333,661