Below is my variable declaration and in the shell script, I am looking for a way to loop over the list of strings to get each item.
output='['a.txt', 'b.txt', 'c.txt', 'd.txt']'
I tried the script below but it is not working as expected
for i in "${output}"; do
echo $i
done
Expected result:
a.txt
b.txt
c.txt
d.txt
CodePudding user response:
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.)
CodePudding user response:
From the documentation of GNU Bash,
"A list is a sequence of one or more pipelines separated by one of the operators ‘;’, ‘&’, ‘&&’, or ‘||’, and optionally terminated by one of ‘;’, ‘&’, or a newline."
Also, you need to remember Bash supports one-dimensional numerically indexed and associative array types, unfortunately, as per my knowledge bash doesn't support a "List" type data structure.
And for that reason you need to modify your variable declaration like the below:
output=("a.txt" "b.txt" "c.txt" "d.txt")