31

I need to read a file using a "Do/While" loop.
How can I read the contents as a string?

Here's my code:

cat directory/scripts/tv2dbarray.txt | while read line
do
  echo "a line: $line"
done

Error:

test.sh: line 4: syntax error near unexpected token `done'
test.sh: line 4: `done'
Adam Liss
  • 47,594
  • 12
  • 108
  • 150
Leonardo
  • 2,273
  • 6
  • 29
  • 32
  • 2
    There's nothing wrong with this code. Is there something else in the script? Perhaps another `while` or `if` or an unbalanced quote, brace, bracket or parentheses? – Dennis Williamson Feb 20 '11 at 16:11
  • `# or - it might be copy-pasted (with some rich text, Which is messing up the file itself)` how-why-what-is this I am typing? uhm; it have (put simply) happened to me a bunch--of-times when I copy-pasting code into libreoffice, then copy-pasting it back(having colored the text) so some in-visible characters also get's copied - really weird - but it still is the same problem; to solve it you just by-hand type it(cat directory...`) (for long files this is a problem) (for short snippets like this one, it's easily and quickly typed) `Just needed to throw that in for any future explorer` – William Martens Oct 20 '22 at 19:45

4 Answers4

118

There's no reason to use cat here -- it adds no functionality and spawns an unnecessary process.

while IFS= read -r line; do
  echo "a line: $line"
done < file

To read the contents of a file into a variable, use

foo=$(<file)

(note that this trims trailing newlines).

gniourf_gniourf
  • 44,650
  • 9
  • 93
  • 104
Adam Liss
  • 47,594
  • 12
  • 108
  • 150
  • 7
    I wish I could upvote this more times and ensure that it was the top result of every Google search. I phrased this question so many ways over the past hour and everytime until now I found answers along the lines of "use cat". Finally, the sane one line answer (which, unlike cat, simply works.) – ArtOfWarfare Apr 29 '13 at 05:56
  • 1
    Thanks for the edit, @gniourf_gniourf -- you learn somthing new every day! – Adam Liss Sep 27 '15 at 15:36
  • @AdamLiss @ArtOfWarfare is there a way to define a variable via that method to also keep num. of "things" or "lines" ? like, "for each line do ECHO LINE but also ECHO NUMBER " ? I don't mean another for or yeah but I thought - do `read` have such a feature? like, read->file line by line's`CONTENTS` into variable_A and at same time, read->file line by line'S NUMBER into `variable_B` ? and I used CAPS at times to just make it more detailed, (so, uhm - I do `not scream`! :) ) if not; thanks anyway - have a great day! – William Martens Oct 18 '22 at 05:35
  • 2
    @WilliamMartens - Yes, but really quickly you hit the point where you have to ask yourself why you're doing so much in bash and not just using Python or another scripting language. (No, I don't know your answer but I'm sure there is one. Search around on SO - I'm sure it's been asked and answered before. Post a new question if it hasn't been.) – ArtOfWarfare Oct 18 '22 at 16:14
  • @ArtOfWarfare yes; thank you - just wanted to check it. Over n out ️ have a great day! :) – William Martens Oct 18 '22 at 18:30
  • 2
    @WilliamMartens:    `i=0; while read line; do ((i=i+1)); echo "Line $i: $line"; done < file`    You could also cheat and use `grep -n` to search for something that will match every line and number the results:    `grep -n '' file | while read...`    @ArtOfWarfare I can't help it. My native language is bash. ️    How wonderful to see a question and answer that are still relevant 10 years later! – Adam Liss Oct 19 '22 at 14:12
  • @AdamLiss **THANKS** Holy.. heavens.. wow - thanks a lot ! Maybe add that to your answer..? as a extra-thing or , yeah - Note I didn't expect to see a reply but in a few decades.. And you just replies TODAY?! :D heh.. made ones day ! cheers! ️ (`it's water`) – William Martens Oct 19 '22 at 16:43
  • This won't echo the last line if the file does not end with a newline character. See https://stackoverflow.com/a/1521498/1091231 for a solution that also works in that case. – pasqal May 13 '23 at 16:43
41
cat file | while read line
do
  echo "a line: $line"
done

EDIT:

To get file contents into a var use:

foo="`cat file`"
Erik
  • 88,732
  • 13
  • 198
  • 189
  • 1
    test.sh: line 5: syntax error near unexpected token `done' test.sh: line 5: `done' – Leonardo Feb 20 '11 at 14:18
  • Please check this once: https://stackoverflow.com/questions/56459572/replace-a-string-in-a-file-with-contents-copied-from-another-file?noredirect=1#comment99510991_56459572 – nr5 Jun 05 '19 at 12:19
4

This should work:

file=path/of/file/location/filename.txt

while IFS= read -r varname; do
    printf '%s\n' "$varname"
done < "$file"
gniourf_gniourf
  • 44,650
  • 9
  • 93
  • 104
prudviraj
  • 3,634
  • 2
  • 16
  • 22
0

try it

while read p
do 
echo $p
done <  directory/scripts/tv2dbarray.txt
pedram shabani
  • 1,654
  • 2
  • 20
  • 30