The syntax of a
for loop is this:
Code:
for variable in <wordlist> ; do
commands
done
Each iteration takes a "word" from the list into the variable and runs the sub-commands. Note that the definition of word depends on shell quoting and/or your IFS setting. So this:
foo bar "baz bum"
...is three words. "baz bum" is considered a single unit.
If the word list contains an unquoted variable, then the variable is first expanded, then word-split and glob expanded by the shell, to create the final word list. But if it's double-quoted, the expanded value is treated as a single unit. That's why you are getting the whole block of text at once; it's being seen as only one "word".
Code:
var='foo bar baz bum'
for word in hello $var "$var" goodbye; do
echo "$word"
done
#output:
hello
foo
bar
baz
bum
foo bar baz bum
goodbye
Notice how unquoting it doesn't work either, because then your text is broken up by whitespace.
Now, to get to the meat of the matter, there's really no way for you to safely do exactly what you want with a
for loop. The shell just isn't capable of safely delimiting variable contents into individual lines in cases like this. The closest you can get is by setting IFS to newline only, but even that means blank lines will be lost.
It's all explained here:
http://mywiki.wooledge.org/DontReadLinesWithFor
So you really need to use a
while+read loop instead, or some other technique.
Code:
while read line; do
echo "$line aaa"
done <<<"$string"
However, since a variable is really designed for holding single, short strings, a better technique may be to store your text in an
array instead, with one line per index. Arrays are
designed for holding lists of things, and so are much better suited for storing multi-lined data.
To convert your scalar variable into an array you can use the
mapfile command (bash4+).
Code:
mapfile -t strarray <<<"$string"
for line in "${strarray[@]}"; do
echo "$line aaa"
done
If you're wondering, both of the techniques above use
here strings to send the contents of the variable to the command's stdin.