Loop with 2 variables in a bash script

5,677

Solution 1

The criteria isnt defined that well, but this is how I would do it:

hosts=(
box001:box001.domain.com
box002:box002.domain.com
box003:box003.domain.com
box004:box004.domain.com
box005:box005.domain.com
)

uri="http://server/api/duplicateobject.htm?id=2928&name=NEWSERVER&host=NEWHOSTNAME&targetid=3120"

for host in "${hosts[@]}"; do
    IFS=":" names=( $host )
    hosturi="${uri/NEWSERVER/${names[0]}}"
    hosturi="${hosturi/NEWHOSTNAME/${names[1]}}"
    echo "$hosturi"
done

Outputs:

http://server/api/duplicateobject.htm?id=2928&name=box001&host=box001.domain.com&targetid=3120
http://server/api/duplicateobject.htm?id=2928&name=box002&host=box002.domain.com&targetid=3120
http://server/api/duplicateobject.htm?id=2928&name=box003&host=box003.domain.com&targetid=3120
http://server/api/duplicateobject.htm?id=2928&name=box004&host=box004.domain.com&targetid=3120
http://server/api/duplicateobject.htm?id=2928&name=box005&host=box005.domain.com&targetid=3120

Advantages:

  • Keeps it clear which server name corresponds with which fqdn.
  • Its pure bash & uses no external anything.

.

If the server name is always going to be the first part of the fqdn, the array can be even simpler and you can have bash figure the server name out from the fqdn.

Solution 2

If both your arrays are the same length, and you just want to be able access the same index in each, here is an example:

for ((i=0; i < ${#newserver[@]}; i++)); do 
  echo ${newserver[i]} ${newhostname[i]};
done;

Solution 3

Your above arrays and:

url="http://server/api/duplicateobject.htm?id=2928&name=NEWSERVER&host=NEWHOSTNAME&targetid=3120"
for ((i=0; i < ${#newserver[@]}; i++));
do
   echo $url | sed 's/NEWSERVER/'${newserver[i]}'/;s/NEWHOSTNAME/'${newhostname[i]}'/'
done

leads to:

http://server/api/duplicateobject.htm?id=2928&name=box001&host=box001.domain.com&targetid=3120
http://server/api/duplicateobject.htm?id=2928&name=box002&host=box002.domain.com&targetid=3120
http://server/api/duplicateobject.htm?id=2928&name=box003&host=box003.domain.com&targetid=3120
http://server/api/duplicateobject.htm?id=2928&name=box004&host=box004.domain.com&targetid=3120
http://server/api/duplicateobject.htm?id=2928&name=box005&host=box005.domain.com&targetid=3120

Solution 4

If you are using bash, you can use associative arrays:

declare -A servers
servers=(
    [box001]=box001.domain.com
    [box002]=box002.domain.com
    [box003]=box003.domain.com
    [box004]=box004.domain.com
    [box005]=box005.domain.com
)

for server in "${!servers[@]}" ; do
    hostname="${servers[$server]}"
    # do something with $server and $hostname
done

The order that you iterate the servers is not defined. For the above example in my version of bash on my host, the order is box001, box003, box002, box005 and box004. YMMV.

Share:
5,677
LVLAaron
Author by

LVLAaron

Updated on September 18, 2022

Comments

  • LVLAaron
    LVLAaron over 1 year

    I am trying to utilize an API. I need to either do some type of "for loop" that replaces or utilizes 2 variables...

    In pseudo..

    # Declare New Servers
    newserver=(
    box001
    box002
    box003
    box004
    box005
    )
    
    
    # Declare hostnames
    newhostname=(
    box001.domain.com
    box002.domain.com
    box003.domain.com
    box004.domain.com
    box005.domain.com
    )
    

    I need to replace NEWSERVER and NEWHOSTNAME in

    http://server/api/duplicateobject.htm?id=2928&name=NEWSERVER&host=NEWHOSTNAME&targetid=3120
    

    so that it looks like this

    http://server/api/duplicateobject.htm?id=2928&name=box001&host=box001.zcloud.com&targetid=3120
    

    I just need it to loop through all of hosts listed.