In your attempt, quoting the variable forced the shell to regard it as a single value. Failing to quote when you need to is a common beginner error, but quoting when you want the shell to split a value on whitespace (and expand wildcards in the result) is also wrong. Perhaps see also When to wrap quotes around a shell variable?
As long as your items are just tokens, you can save them in a string.
output='a.txt b.txt c.txt d.txt'
for item in $output; do
echo "$item" # remember quotes here
done
In isolation, the variable doesn't buy you anything, though.
for item in a.txt b.txt c.txt d.txt
do
...
or, if all you want is to print the tokens one by one, simply
printf '%s\n' a.txt b.txt c.txt d.txt
The only data type in sh
is a string. There is no simple and safe way to store a sequence of items which require quoting in a variable. (If you can completely control the input, and know what you are doing, try eval
; but often, one or both of these conditions are not true.)
As suggested above, if you can avoid saving the values in a variable, you can use any quoting you like!
for item in "an item" another \
'yet one more (with "nested quotes" even, see?)'
do
echo "$item" # now the quotes are important!
done
Bash and Ksh etc have arrays, so you can do things like
items=("an item" another 'yet one more (with "nested quotes" even, see?)')
printf '%s\n' "${items[@]}"
but this is not available in plain sh
.
(For what it's worth, you also cannot nest quotes the way you tried to.
input='['a.txt', '
creates a string consisting of (quoted) [
immediately adjacent to (unquoted) a.txt
imrediately adjacent to (quoted) comma and space. The shell will simply join together the adjacent strings into a single string after quote removal.)