anarchy
anarchy

Reputation: 5204

Iterate over a text file line by line within a for loop in a shell script

I have a txt file that looks like this called locations.txt:

location-1a
location-2c
location-3d
location-4
location-5a
...

I wish to iterate over the locations.txt file within my for loop, each location should be used for 5 nodes, then the next location should be used. so for example, I want the following commands to run,

server create --location location-1a node-1
server create --location location-1a node-2
server create --location location-1a node-3
server create --location location-1a node-4
server create --location location-1a node-5
server create --location location-2c node-6

.....

So far, I only have the following script called script.sh with takes an argument from the cli. I can't change the location like I want to.

mapfile -t locationArr < ~/Documents/files/locations.txt
serverCounter=1
locationCounter=1
counter=1

counter=1
for (( i = 1; i <= $1; i++ ))
do
 server create --location $locationArr[$locationCounter] node-$i
 counter=$((counter+1))
 if [ $counter == 5 ]
 then
  counter=1
  locationCounter=$((locationCounter+1))
done

I want something like

if counter == 5:
 counter=0
 nextline 

So for example if I run script.sh 11, I want the following result,

server create --location location-1a node-1
server create --location location-1a node-2
server create --location location-1a node-3
server create --location location-1a node-4
server create --location location-1a node-5
server create --location location-2c node-6
server create --location location-2c node-7
server create --location location-2c node-8
server create --location location-2c node-9
server create --location location-2c node-10
server create --location location-3d node-11

How do I iterate over the location.txt file within my for loop? Should I convert the text file into some sort of list variable?

Upvotes: 1

Views: 1271

Answers (3)

L&#233;a Gris
L&#233;a Gris

Reputation: 19685

Done with single loop, no Bashism POSIX syntax:

#!/usr/bin/env sh

i=0
while [ $i -lt "$1" ] && {
  [ $((i % 5)) -ne 0 ] || IFS= read -r line || [ "$line" ]
}; do
  server create --location "$line" "node-$((i = i + 1))"
done <locations.txt

Upvotes: 1

markp-fuso
markp-fuso

Reputation: 35556

General outline:

  • outer loop for reading locations from locations.txt
  • inner loop for generating a max of 5 nodes for a given location
  • each time a node is generated increment a count
  • if the counter > input 'max' then break out of loops

One implementation of the above:

max=${1}
curr=1

while read -r location
do
    for i in {1..5}
    do
        echo "server create --location ${location} node-${curr}"
        curr=$((curr+1))
        [ ${curr} -gt ${max} ] && break 2
    done
done < locations.txt

Test run with max=${1}=11:

server create --location location-1a node-1
server create --location location-1a node-2
server create --location location-1a node-3
server create --location location-1a node-4
server create --location location-1a node-5
server create --location location-2c node-6
server create --location location-2c node-7
server create --location location-2c node-8
server create --location location-2c node-9
server create --location location-2c node-10
server create --location location-3d node-11

OP can add additional checks for max being an integer greater than 0.

Upvotes: 1

hesham_EE
hesham_EE

Reputation: 1165

This is my attempt:

counter=1
while IFS= read -r line
do
    for (( i=1; i <= 5 && $counter <= $1; i++ ))
    do
     server create --location $line node-$counter
     counter=$((counter+1))
    done 
done < ~/Documents/files/locations.txt

The output with 11:

server create --location location-1a node-1
server create --location location-1a node-2
server create --location location-1a node-3
server create --location location-1a node-4
server create --location location-1a node-5
server create --location location-2c node-6
server create --location location-2c node-7
server create --location location-2c node-8
server create --location location-2c node-9
server create --location location-2c node-10
server create --location location-3d node-11

Upvotes: 3

Related Questions