Home > Enterprise >  Shell script to loop over the list of strings
Shell script to loop over the list of strings

Time:06-29

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")
  • Related