1. Introduction
Using multiple variables within a loop is particularly beneficial when dealing with array-structured data. Additionally, it proves advantageous when using a C-style syntax for iterative processing.
In this tutorial, we’ll discuss how to use multiple variables in a for loop in the shell.
First, we’ll discuss the classic C-style syntax method. After that, we’ll explore the nested loop method to use multiple variables in a for loop, followed by a discussion on custom delimiter approach with a for loop. Lastly, we’ll look into the use of the read command with while.
2. Using the C-Style for Loop
To begin with, we’ll use multiple variables in a C-style loop. The C-style syntax is often used in the context of the for loop for complex scenarios. Notably, we employ this type of loop in situations requiring more precise control over variables and conditions relative to a simple for loop. The syntax is similar to the C programming language.
Not all shells support C-style for loops, so using multiple variables in such loops may not be universally applicable across different shell environments.
First, let’s consider a simple shell for loop:
$ cat simple_for.sh
#!/bin/bash
echo "Simple for loop example:"
for number in {1..5}; do
echo "Number: $number"
done
We use the simple shell for loop to iterate over a list and print each of the numbers. Notably, this loop type has a fairly simple syntax, making it easy to use for basic iteration tasks.
On the other hand, let’s check the C_style.sh script:
$ cat C_style.sh
for ((i=1, j=10; i<=5; i++, j--)); do
echo "i: $i, j: $j"
done
Now, we make the file executable using the chmod command, and run the script:
$ chmod +x C_style.sh
$ ./C_style.sh
i: 1, j: 10
i: 2, j: 9
i: 3, j: 8
i: 4, j: 7
i: 5, j: 6
In the above code, the initial loop header action involves initializing two variables. Here, we initialize i to 1 and j to 10. Next, we place a condition that the loop should continue as long as i is less than or equal to 5. After each iteration, i is incremented by 1, and j is decremented by 1. Upon satisfying the condition, the loop terminates automatically.
Within the loop body, we utilize the echo command to display the values of variables i and j.
In summary, the code utilizes two variables in the for loop and displays the output of both variables at each step.
3. Using Nested for Loops
In the same way, we can utilize a nested for loop to use multiple variables for iterating over different types of elements.
Nested loops are convenient for performing operations on combinations of elements from various sets or generating patterns and grids. Also, they provide a structured way to traverse and manipulate data.
For instance, to iterate through two different text files, we’ll use nested for loops.
3.1. Example Script
In this approach, we use two files num.txt and char.txt, and read data from these files. Next, we store the filenames in the num and ch variables respectively:
$ cat test.sh
#!/bin/bash
num="num.txt"
ch="char.txt"
int1=0
for i in `cat $num` do
int1=$(( $int1+1 ))
for j in `cat $ch|tail -n +$int1` do
echo $i " " $j
break
done
done
After that, we initialize a counter variable int1 to 0. Moreover, the outer for loop iterates over each value in num.txt. Also, the int1 counter increments by 1 after each iteration using parameter expansion.
Subsequently, the inner for loop iterates over each value in char.txt, starting from the line number specified by the current value of int1:
- cat $ch outputs the contents of the file specified by the variable $ch
- tail -n +$int1 outputs all lines starting from line number $int1 onwards
- $(…) performs command substitution, replacing the expression with the output of the enclosed commands
To elaborate, for j in $(cat $ch | tail -n +$int1) sets up a loop where j takes on each value (word) in the output of cat $ch | tail -n +$int1. The loop iterates over each word in the lines of char.txt starting from the line specified by int1.
Lastly, we use the echo command to output the values of $i and $j.
The break statement exits the inner loop after processing the first value from char.txt. Additionally, the done command ends the outer loop, and the script continues to the next iteration of the outer loop with the subsequent value from num.txt.
So, let’s test the script.
3.2. Demonstration
First, let’s check our two sample files:
$ cat num.txt
1 2 3 4 5 6 7 8 9
$ cat char.txt
a
b
c
d
e
f
g
h
i
j
Moreover, we’ll make the script executable and run it:
$ chmod +x nestedLoop.sh
$ ./nestedLoop.sh
1 a
2 b
3 c
4 d
5 e
6 f
7 g
8 h
9 i
In summary, the script reads numbers from num.txt in the outer loop and values from char.txt in the inner loop. For each value, it outputs the pair of values.
4. Using a Custom Delimiter With a for Loop
An alternative approach for utilizing multiple variables involves employing IFS with a for loop. Thus, we use multiple variables within the loop body.
In practice, the IFS variable is used to tokenize a string into fields based on the specified delimiter. To elaborate, this special shell variable determines how Bash recognizes word boundaries in strings.
In this method, we’ll use IFS with a for loop to iterate over different variables.
Now, let’s view the script:
$ cat IFS.sh
#!/bin/bash
IFS=":"
for n in $(cat data.txt);do
fields=($n)
first="${fields[0]}"
second="${fields[1]}"
echo "$first"
echo "$second"
done
The data file consists of some sample data:
$ cat data.txt
John:20
Doe:30
Bob:40
David:50
Let’s make the script executable and run it:
$ chmod +x IFS.sh
$ ./IFS.sh
John
20
Doe
30
Bob
40
David
50
In this script, we see that the IFS is set to the colon : character. Next, the for loop iterates over each line in the data.txt file. Each line is then assigned to the n variable.
Moreover, fields=($n) splits the value of n into an array called fields using the specified IFS. Then, first=”${fields[0]}”* and second=”${fields[1]}” assigns the first and second fields of the array fields to the variables first and *second, respectively.
Lastly, we use the echo command to print the output.
5. Using Multiple Variables in a while Loop With read
Similarly, we can use multiple variables with a while loop by combining it with the read command.
First, we’ll take a look at the sample file we’re working with:
$ cat data.txt
foo|bar
baz|foobar
jim|30
kim|40
chuck|60
50|20
Next, let’s view the whileloop.sh script:
$ cat whileloop.sh
#!/bin/bash
while IFS='|' read -r i j; do
echo "$i:$j"
done < "data.txt"
Now, let’s execute and check the output of the script:
$ chmod +x whileloop.sh
$ ./whileloop.sh
foo:bar
baz:foobar
jim:30
kim:40
chuck:60
50:20
The above code uses a while loop with IFS to process the input from < “file.txt”. Here, IFS is set to the pipe character (|), indicating that fields within each line should be separated by this particular character.
Next, read -r i j uses the read command to get each line from the input, i.e., the data.txt contents. After that, it assigns the first field to variable i and the second field to variable j.
Furthermore, inside the loop, the echo command prints the values of i and j, separated by a colon.
Hence, this script reads each line from file.txt, and uses the pipe character as a field separator. Next, it outputs the first and second field values separated by a colon.
6. Conclusion
In this article, we gained insights into utilizing multiple variables within a shell script for loop.
First, we explored the C-style for loops, characterized by their resemblance to the syntax used in the C programming language. This method is for managing more intricate loop control structures.
After that, we discussed the nested loop method to use multiple variables in the for loop. Lastly, we discussed employing a read command with a while loop to use multiple variables.