Learn by reading through in order

Loops — Processing Files One by One with for

This article is part of the Linux Course, where you master practical Linux skills from scratch, from basic commands through to shell scripting.
Loop over a file list with for f in *.txt, repeat conditionally with while [ "$i" -le 3 ] and until, skip blank values with continue, and stop at a limit with break — illustrated and practiced in a browser terminal.

Process a list in order — for

for takes the values you give it one at a time and runs the same work on each.

The form is for v in a b c; do ... done, where v becomes a, then b, then c in turn.

What sits between do and done is the body that repeats.

You can list the values directly, use a file pattern like *.txt, or feed in the output of $(...) from a command.

Write for f in *.txt and each .txt file in the current directory goes into f in turn, so you can write per-file work.

Using $(...) as in for line in $(cat list.txt) lets you loop over the output of a command.

This is how you write summaries of a file list or batch processing across several files.

for env in dev stg prod; do        # process the listed values in turn
  echo "deploying to $env"
done
for f in *.sh; do                  # process the .sh files in turn
  echo "script: $f"
done
How a for loop goes around
for f in *.txtRun body(do … done)next item → fend at donewhen none leftrepeat for each item
for pulls items from the list into f one at a time and runs the body, then finishes at done once the items run out.
SyntaxMeaningExample
for v in a b c; do … doneprocess the listed values in turnfor v in dev stg prod; do echo $v; done
for f in *.txt; do …process matching files in turnfor f in *.txt; do wc -l "$f"; done
for x in $(cmd); do …process command output in turnfor d in $(ls); do echo $d; done
do … donestart and end of the loop bodyfor v in a b; do echo $v; done

Write a script that loops over a file list and totals the counts.

① Open count-lines.sh with vi count-lines.sh, press i to enter insert mode, and write #!/bin/sh on the first line.

② Inside the script, create a few sample files, loop a file pattern with for, count the lines of each file one by one, and print the total.

③ Press Esc, save with :wq, then add execute permission.

④ Run the script and confirm that each file and the total are printed.

⑤ If you are unsure what to write, copy the text in the answer panel and paste it into vi insert mode. (Run it correctly to reveal the explanation.)

Linux console
0 / 3 completed
Loading Linux Terminal...

Loop on a condition — while / until

while repeats as long as the condition is true.

As in while [ "$i" -lt 3 ]; do ... done, you increment a counter inside the body to head toward the end.

until is the opposite — it repeats until the condition becomes true.

It suits work where the number of rounds is not fixed in advance.

i=1
while [ "$i" -le 3 ]; do          # repeat while i is 3 or less
  echo "try $i"
  i=$((i + 1))
done                              # try 1 / try 2 / try 3
i=1
until [ "$i" -gt 3 ]; do          # repeat until the condition becomes true
  echo "i=$i"
  i=$((i + 1))
done                              # i=1 / i=2 / i=3
while vs until
while [ i ≤ 3 ]condition truerun bodyuntil [ i > 3 ]condition falserun bodywhile: repeat while trueuntil: repeat till true
while repeats the body while the condition is true; until repeats it until the condition becomes true. Both advance a counter in the body to head toward the end.
SyntaxMeaningExample
while [ cond ]; do … donerepeat while the condition is truewhile [ "$i" -lt 3 ]; do …; done
until [ cond ]; do … donerepeat until the condition becomes trueuntil [ -f done.flag ]; do …; done

Write a retry script that repeats work while counting the rounds.

① Open retry.sh with vi retry.sh, press i to enter insert mode, and write #!/bin/sh on the first line.

② Set up a counter variable, loop with while up to a limit while printing the attempt number, and increment the counter inside the body.

③ Confirm that rewriting the same work as until [ "$i" -gt "$max" ] gives the same result.

④ Press Esc, save with :wq, then add execute permission.

⑤ Run the script and confirm it repeated the set number of times.

⑥ If you are unsure what to write, copy the text in the answer panel and paste it into vi insert mode.

Linux console
0 / 3 completed
Loading Linux Terminal...

Control a for loop — break / continue

Even partway through a for loop, you can change the flow with break and continue.

continue skips the rest of that round and moves on to the next item, while break ends the loop itself.

Combine them with a condition as in if [ condition ]; then continue; fi or if [ condition ]; then break; fi to skip items you don't need or stop once you have enough.

for n in 1 2 3 4 5; do
  if [ "$n" -eq 3 ]; then continue; fi  # skip 3
  if [ "$n" -eq 5 ]; then break; fi     # break out at 5
  echo "n=$n"
done                                    # n=1 / n=2 / n=4
break / continue flow in for
n=1run bodyprint n=1n=2run bodyprint n=2n=3continueskip rest, nextn=4run bodyprint n=4n=5breakend the loopto next itemcontinue: skip this roundbreak: exit the loop
for runs the body in order from n=1. At n=3 the continue skips the rest and moves on, and at n=5 the break ends the loop itself (output is n=1 / n=2 / n=4).
SyntaxMeaningExample
continueskip this round and go to the nextif [ -z "$x" ]; then continue; fi
breakexit the loop partway throughif [ "$n" -gt 100 ]; then break; fi

Write a collection script that skips blank values and stops at a limit.

① Open collect.sh with vi collect.sh, press i to enter insert mode, and write #!/bin/sh on the first line.

② Loop a list of values with for, skip empty or unwanted values with continue, and exit the loop with break once you reach the limit.

③ Press Esc, save with :wq, then add execute permission.

④ Run the script and confirm the skipped values and the point where it stopped.

⑤ If you are unsure what to write, copy the text in the answer panel and paste it into vi insert mode.

Linux console
0 / 3 completed
Loading Linux Terminal...

Control a while loop — break / continue

On top of the condition check in while, using break and continue lets you stop early or skip a round.

continue skips that round and goes back to the condition check, while break exits the loop without waiting on the condition.

Watch out here: if you don't place the counter update at the top of the body (before continue), the skipped round won't update it and the loop never ends.

i=0
while [ "$i" -lt 10 ]; do
  i=$((i + 1))                          # advance at the top
  if [ "$i" -eq 3 ]; then continue; fi  # skip the 3rd round
  if [ "$i" -eq 6 ]; then break; fi     # break out on the 6th round
  echo "attempt $i"
done                                    # attempt 1 / 2 / 4 / 5
break / continue flow in while
i=1run bodyattempt 1i=2run bodyattempt 2i=3continueback to checki=4run bodyattempt 4i=5run bodyattempt 5i=6breakend the loopto next roundcontinue: back to checkbreak: exit the loop
while runs the body while the condition is true, advancing i by 1 each time. At i=3 the continue goes back to the condition check, and at i=6 the break ends the loop without waiting on the condition (output is attempt 1 / 2 / 4 / 5).
SyntaxMeaningExample
continueskip this round, back to the checkif [ $((i % 3)) -eq 0 ]; then continue; fi
breakexit the loop without waiting on the conditionif [ "$found" -ge 4 ]; then break; fi
where to update the counterupdate it before continueput i=$((i + 1)) at the top of the body

Write a scan script that loops with while, skips the rounds it doesn't need, and stops once it has the number of items it needs.

① Open scan.sh with vi scan.sh, press i to enter insert mode, and write #!/bin/sh on the first line.

② Set up a counter, loop with while up to a limit, and advance the counter by 1 at the top of the body.

③ Skip rounds that meet a certain condition with continue, and exit the loop with break once you reach the number of items you need.

④ Press Esc, save with :wq, then add execute permission.

⑤ Run the script and confirm the skipped rounds and the point where it stopped.

⑥ If you are unsure what to write, copy the text in the answer panel and paste it into vi insert mode.

Linux console
0 / 3 completed
Loading Linux Terminal...
QUIZ

Knowledge Check

Answer each question one by one.

Q1What does for f in *.txt; do ... done loop over?

Q2Which keyword repeats while the condition is true?

Q3Which one skips just that round and moves on to the next?