0

I want to try my hand at Arrays in AWK. I've written a script that will scp multiple files to multiple IP addresses and I'm curious about a specific part of the script.

This is my script

#! /bin/awk -f
{
        iplist[$1];
        filelist[$2];
}
END {
        for (i in filelist)
        for (q in iplist){
                print "scp"filelist[i],i " root@"iplist[q],q;
        }
}

The part that I don't understand is here

print "scp"filelist[i],i " root@"iplist[q],q;

Why do I need to have the ',i' and the ',q'?

What is the purpose of these? Without them the script runs but does not place the values of the variables in the output.

Example of file the arrays are coming from

test_ip

xx.x.xx.21      /cat/dog/bird/
xx.x.xx.22      /dog/cat/test/
xx.x.xx.23      /home/foo/bar/

With ,i & ,q

scp /cat/dog/bird/ root@ xx.x.xx.23
scp /cat/dog/bird/ root@ xx.x.xx.21
scp /cat/dog/bird/ root@ xx.x.xx.22
scp /home/foo/bar/ root@ xx.x.xx.23
scp /home/foo/bar/ root@ xx.x.xx.21
scp /home/foo/bar/ root@ xx.x.xx.22
scp /dog/cat/test/ root@ xx.x.xx.23
scp /dog/cat/test/ root@ xx.x.xx.21
scp /dog/cat/test/ root@ xx.x.xx.22

Without ,i & ,q

scp root@
scp root@
scp root@
scp root@
scp root@
scp root@
scp root@
scp root@
scp root@
2
  • Get the book "Effective Awk Programming, Third Edition" by Arnold Robbins. Commented Jan 9, 2015 at 16:51
  • awk concatenates strings without any explicit operator. The print operator gets 3 arguments because of the 2 commas. For practical purposes, the print could be written more clearly as: print "scp", i, "root@", q (the semicolon isn't necessary). Commented Jan 9, 2015 at 17:04

1 Answer 1

1

Its not the i and q that is useless but filelist[i] and iplist[q]

awk '{
        iplist[$1];
        filelist[$2];
}
END {
        for (i in filelist)
        for (q in iplist){
                print "scp",i " root@",q;
        }
}' input
scp /dog/cat/test/ root@ xx.x.xx.21
scp /dog/cat/test/ root@ xx.x.xx.22
scp /dog/cat/test/ root@ xx.x.xx.23
scp /cat/dog/bird/ root@ xx.x.xx.21
scp /cat/dog/bird/ root@ xx.x.xx.22
scp /cat/dog/bird/ root@ xx.x.xx.23
scp /home/foo/bar/ root@ xx.x.xx.21
scp /home/foo/bar/ root@ xx.x.xx.22
scp /home/foo/bar/ root@ xx.x.xx.23

The awk arrays are associative. That is when you write

iplist[$1] the key that is used is the value in the first colum of the input, which being the list

iplist[xx.x.xx.21]      
iplist[xx.x.xx.22]
iplist[xx.x.xx.23]

Now the for in loop can be used to iterate through the keys in the array. That is when you write

for (q in iplist)

it iterates throught the keys in iplist. That is

If you try something like

$ awk '{
        iplist[$1];
}
END {
        for (q in iplist){ 
                print q;
        }                               
}' inputFile

xx.x.xx.21
xx.x.xx.22
xx.x.xx.23
Sign up to request clarification or add additional context in comments.

3 Comments

Huh, almost every other language uses for ... in loops to iterate values, not keys. I never knew that awk did it differently.
@Mr.Llama no, they don't, most other languages do not have an in operator to traverse arrays.
Shoot, I was thinking for each loops. I stand corrected.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.