Skip to content
Advertisement

How to iterate over two arguments in the sh linux shell

I have two sets of arguments: a = "5 7 1" and b = "dogs cats horse"

They should come in pairs: 5 matches dogs, 7 matches cats and 1 matches horse

They also should do this in one line:

I have 5 whatever dogs whatever whatever
I have 7 whatever cats whatever whatever
I have 1 whatever horse whatever whatever

The problem is that the $a and $b can have hundreds of arguments, so writing many lines like the above ones isn’t really an option.

I found something like the following which do the job:

a = "5 7 1"
b = "dogs cats horse"

set -- $a
for i in $b; do
  echo "I have $i whatever $1 whatever whatever"
  shift 1
done

but I wonder if there’s some other alternatives.

Basically when we have just 3 pairs, it’s easy to know in the script which values from $a correspond to which values of $b. Now imagine having 200 of values in both sets and you have to change the $b values where $a values are 50 and 157. Of course it’s just an example — any values can change in both sets with time. So is there a better way to map the values something like 5:dogs, 7:cats and 1:cats? In this way if numbers of dogs changes to 4 I can easily find what to change.

Advertisement

Answer

If you can use ‘bash’, you can use the associative array (and mapfile/readarray), but this will not scale well to the number of items you mention (200+).

For a solution that is not bash specific: Consider storing the pairs in a file (or inline document, see below).

dogs:5
cats:7
horse:1

Then use a script:

while IFS=: read k v ; do
  echo "I have $v whatever $k whatever whatever"
done < file.txt

You can also embed the map into << document.

while IFS=: read k v ; do
  echo "I have $v whatever $k whatever whatever"
done <<EOF
dogs:5
cats:7
horse:3
EOF


User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement