Feng Yu
Feng Yu

Reputation: 1493

Bash for loop how to solve variable with space?

In some case, quotes can solve a param which contains space.

$ command "param 1" "param 2" ...

And it can also work for for loop.

$ for v in a "b c" "d e"
do
    echo "|$v|"
done
|a|
|b c|
|d e|

But when I use a variable after in, it not working:

$ var='a "b c" "d e"'
$ echo $var
  a "b c" "d e"
$ for v in $var
  do
      echo "|$v|"
  done
 |a|
 |"b|
 |c"|
 |"d|
 |e"|

It not working. How do I resolve this problem ?

Upvotes: 2

Views: 825

Answers (2)

John1024
John1024

Reputation: 113844

That is why arrays were invented:

$ var=(a "b c" "d e")
$ for v in "${var[@]}"; do echo "|$v|"; done
|a|
|b c|
|d e|

Discussion

Consider:

var='a "b c" "d e"'

The problem with the above is that, once you quote a quote, it loses its magic. The double-quotes inside the single-quoted string above are characters, just like any other characters: they no longer bind anything together. That is why the output looks like this:

|a|
|"b|
|c"|
|"d|
|e"|

Reading arrays from the terminal

Arrays can be entered in newline-separated form using readarray:

$ readarray -tn3 var
a 
b c
d e
$ for v in "${var[@]}"; do echo "|$v|"; done
|a|
|b c|
|d e|

-n3 limits the input to three lines. -t tells readarray to discard the newline character.

Upvotes: 5

vastlysuperiorman
vastlysuperiorman

Reputation: 1784

As mentioned in comments and another answer, use an array if you can. That really is the best option.

If you are forced to work with strings (for some odd reason not described in your question) change your internal field separator, and then use your custom defined one to separate fields.

#Copy the current IFS
SaveIFS=$IFS
IFS=';'

var='a;b c;d e;'
for v in $var; do
    echo $v
done

#Revert when done
IFS=$SaveIFS

Upvotes: 0

Related Questions