C.W.K.
Stream
Lesson 04 of 12 · published

Loops: for, while, until

~12 min · for, while, until, loops

Level 0Window Tourist
0 XP0/95 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

for over a list

for f in *.txt; do
  echo "processing $f"
done

The list is anything: glob results, an explicit list, command substitution, an array.

for over a range

# C-style (bash/zsh)
for ((i=0; i<10; i++)); do echo $i; done
# brace expansion
for i in {1..10}; do echo $i; done
for i in {1..10..2}; do echo $i; done   # step

for over array

files=("a.txt" "b.txt" "c.txt")
for f in "${files[@]}"; do echo "$f"; done

"${arr[@]}" expands to one quoted token per element. "${arr[*]}" joins them into one string with IFS — almost always wrong.

while

i=0
while [[ $i -lt 5 ]]; do
  echo $i
  ((i++))
done

# Read a file line by line
while IFS= read -r line; do
  echo "> $line"
done < input.txt

IFS= read -r is the safe form — preserves leading/trailing whitespace and backslashes. Use it for any line-by-line file read.

until — the inverse of while

until ping -c1 server.local; do
  echo 'waiting...'
  sleep 5
done

break and continue

break exits the current loop. break 2 exits two nested levels. continue skips to the next iteration.

Code

Read a file line by line·bash
while IFS= read -r line; do
  [[ -z "$line" || "$line" == \#* ]] && continue
  echo "config: $line"
done < ~/.config/myapp.conf

External links

Exercise

Write a loop that lists every .zshrc config line that's neither a comment nor blank: while IFS= read -r l; do [[ -z "$l" || "$l" == \#* ]] && continue; echo "$l"; done < ~/.zshrc.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.