LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (http://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   bash reads one less line (http://www.linuxquestions.org/questions/linux-newbie-8/bash-reads-one-less-line-862198/)

ted_chou12 02-12-2011 04:10 AM

bash reads one less line
 
Hi, I am using this code:
Quote:

while read line ; do
...
done
to read file line by line, but there is a problem when the text file lacks an empty line:
Code:

1
2
3
4
5
//extra spaced line

This the script reads fine up to line 5
but with:
Code:

1
2
3
4
5

without the last spaced line, script only reads to line 4. fifth line is ignored. Is there anyway to force it read the last line?
Thanks

grail 02-12-2011 04:17 AM

Seeing the windows icon on your status makes me wonder if the file being read is created under Windows or linux?
If windows you need to remove the extraneous newline format from the end.

ted_chou12 02-12-2011 04:33 AM

yeah, I am using windows os, but im using winscp ascii to edit the text files. But if I remove those extra lines at the end, the script doesn't read up to the last non-empty line.

grail 02-12-2011 05:08 AM

Try running od -c on the file and see what characters are there or if you have it try running dos2unix over the file.
The action of not reading the last line is not in any way to do with the while loop.

Kenhelm 02-12-2011 10:05 AM

This reproduces the problem
Code:

echo -n '1
2
3
4
5' | while read line; do
      echo "$line"
    done
1
2
3
4

grep '^' will add a newline to the end of a file if there isn't one already there. Try
Code:

grep '^' file | while read line; do
                  echo "$line"
                done
# Or

while read line; do
  echo "$line"
done < <(grep '^' file)


colucix 02-12-2011 10:25 AM

The line remains in the input buffer when the loop terminates, so that you can process it after the loop itself:
Code:

while read line
do
  echo $line
done < file
echo $line

but you have to find a way to check if the file has an ending newline before you attempt to process the last line (otherwise it will be processed twice, one in the loop and one after). In alternative follow the suggestion by Kenhelm. Another option is awk:
Code:

while read line
do
  echo $line
done < <(awk 1 file)



All times are GMT -5. The time now is 02:05 AM.