Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I read that it is bad to write things like for line in $(command), the correct way seem to be instead:

command | while IFS= read -r line; do echo $line; done

This works great. But what if what I want to iterate on is the contents of a variable, not the direct result of a command?

For example, imagine that you create the following file quickfox:

The quick brown
foxjumps\ over -
the
lazy ,
dog.

I would like to be able to do something like this:

# This is just for the example,
# I could of course stream the contents to `read`
variable=$(cat quickfox);
while IFS= read -r line < $variable; do echo $line; done; # this is incorrect
share|improve this question
up vote 4 down vote accepted

In modern shells like bash and zsh, you have a very usefull `<<<' redirector that accepts a string as an input. So you would do

while IFS= read -r line ; do echo $line; done <<< "$variable"

Otherwise, you can always do

echo "$variable" | while IFS= read -r line ; do echo $line; done
share|improve this answer
    
Sorry, I should have thought about echoing the contents of course. But thanks for the quick answer anyway! – Sheljohn Apr 11 at 19:17
    
you need to double-quote $variable when you use it, otherwise the while loop will get only one line of input. See, for example, the difference in output between echo $variable vs echo "$variable" or cat <<< $variable vs cat <<< "$variable". – cas Apr 11 at 22:54
    
@cas Actually it depends on what is inside $variable. In the case presented by the OP ("variable=$(cat quickfox)") it works without the additional quotes. But for the general case, you're right. I edit my answer. Thanks. – lgeorget Apr 12 at 6:55
    
The variable=$(cat quickfox) in the OP's question itself provides an example of what I was talking about. Using that $variable inside double-quotes includes the newlines, using it without has the newlines translated to spaces by the shell. If you're reading and processing line-by-line, this makes a huge difference - with the former you have multiple input lines, with the latter you have just one input line. The input data is superficially similar but, in practice, completely different in those two cases. – cas Apr 12 at 8:57
    
for example: with that input data, cat <<< "$variable" | wc -l returns 5. cat <<< $variable | wc -l returns 1. If you want/need to preserve whitespace (including newlines, tabs, single or multiple spaces) in a variable then you MUST double-quote the variable when you use it, otherwise they'll all be transformed into a single space between each "word". – cas Apr 12 at 8:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.