Bash Loops: for, while and until
Loops repeat commands. They are the main reason scripts save so much time: one loop can process a thousand files.
for Loop over a List
Example
for city in Karachi Lahore Quetta Peshawar; do
echo "Branch in $city"
doneBranch in Karachi Branch in Lahore Branch in Quetta Branch in Peshawar
The code between do and done runs once for each item.
for Loop over a Range
{1..5} makes the numbers 1 to 5. A third number sets the step.
Example
for i in {1..5}; do
echo -n "$i "
done
echo
for i in {0..20..5}; do
echo -n "$i "
done
echo
for ((i = 3; i > 0; i--)); do
echo "$i..."
done
echo "Go!"1 2 3 4 5 0 5 10 15 20 3... 2... 1... Go!
echo -n prints without a new line. The (( )) form works like the for loop in C or Java.
Looping over Files
Combine for with a wildcard to work on many files at once:
Example
mkdir -p photos && cd photos
touch img1.jpg img2.jpg notes.txt
for file in *.jpg; do
mv "$file" "karachi-$file"
done
lskarachi-img1.jpg karachi-img2.jpg notes.txt
This renames every .jpg file in one go. Doing that by hand for 500 photos would take ages.
Always write "$file" with quotes. Without them, a file called my photo.jpg would be split into two words and the command would fail.
while Loop
while repeats as long as the condition is true:
Example
balance=1000
months=0
while [ "$balance" -lt 2000 ]; do
balance=$((balance + 300))
months=$((months + 1))
done
echo "Balance $balance after $months months"Balance 2200 after 4 months
until Loop
until is the opposite of while: it repeats until the condition becomes true.
Example
count=1
until [ "$count" -gt 3 ]; do
echo "Attempt $count"
((count++))
doneAttempt 1 Attempt 2 Attempt 3
Reading a File Line by Line
while read is the standard way to process a file one line at a time:
Example
printf "Ali 85\nSara 92\nHamza 78\n" > marks.txt
while read -r name score; do
echo "$name scored $score"
done < marks.txtAli scored 85 Sara scored 92 Hamza scored 78
read splits each line at spaces, so the first word goes into name and the second into score. -r keeps backslashes as they are.
break and continue
| Keyword | What it does |
|---|---|
break | Stops the loop completely |
continue | Skips to the next round |
Example
for n in {1..10}; do
if [ $((n % 2)) -eq 0 ]; then
continue
fi
if [ "$n" -gt 7 ]; then
break
fi
echo -n "$n "
done
echo1 3 5 7
Exercise
Exercise
Which word ends the body of a for loop in Bash?
