Bash: For Loop
A `for` loop iterates over a list of items, executing commands for each of them. It's a great tool for processing files, strings, or command outputs.
Iterating over a list
for fruit in apple banana orange; do
echo "I like $fruit"
done
A `for` loop iterates over a list of items, executing the commands between `do` and `done` for each item. The list can be a set of words, a command's output, or a glob pattern (e.g., `*.txt`).
Note: By default, Bash splits a string at each space. To handle file names or words with spaces, you should use double quotes around variables (e.g., `"file with spaces.txt"`).
Word Splitting Explained
Word splitting is a core mechanism in Bash that determines how an unquoted string is divided into separate arguments. This process happens after variable expansion but before the command or loop is executed.
Without quotes (word splitting)
mystring="apple banana orange"
for word in $mystring; do
echo "$word"
done
# Result:
# apple
# banana
# orange
When the variable $mystring is **unquoted**, Bash uses the IFS (Internal Field Separator) variable to split it. By default, IFS contains space, tab, and newline characters. The loop then iterates over each of the resulting words.
With quotes (single element)
mystring="apple banana orange"
for word in "$mystring"; do
echo "$word"
done
# Result:
# apple banana orange
When the variable is **quoted** ("$mystring"), Bash treats the entire value as a single, indivisible string. The word splitting mechanism is suppressed, and the loop iterates only once. This is the **most important** reason to always quote your variables.
Using a custom separator (IFS)
The IFS (Internal Field Separator) variable determines how Bash splits a string into words. **It is a string itself**, and every character within the IFS string is treated as a delimiter. By temporarily changing its value, you can iterate over strings that use a different delimiter, like a comma or a newline character.
# A string with custom delimiters
MY_STRING="apple,banana,orange"
# Temporarily set IFS to a comma for this loop
IFS=','
for fruit in $MY_STRING; do
echo "Processing: $fruit"
done
Iterating with a newline separator
# A string with newline delimiters
MY_STRING="apple
banana
orange"
# The default IFS handles newlines
for fruit in $MY_STRING; do
echo "Processing: $fruit"
done
Because the newline character is part of the default IFS, the loop will automatically iterate over each line as a separate item. This is a common pattern for processing file contents.