How to use `while read` (Bash) to read the last line in a file if there’s no newline at the end of the file?

Solution 1:

I use the following construct:

while IFS= read -r LINE || [[ -n "$LINE" ]]; do
    echo "$LINE"
done

It works with pretty much anything except null characters in the input:

  • Files that start or end with blank lines
  • Lines that start or end with whitespace
  • Files that don't have a terminating newline

Solution 2:

In your first example, I'm assuming you are reading from stdin. To do the same with the second code block, you just have to remove the redirection and echo $REPLY:

DONE=false
until $DONE ;do
read || DONE=true
echo $REPLY
done

Solution 3:

Using grep with while loop:

while IFS= read -r line; do
  echo "$line"
done < <(grep "" file)

Using grep . instead of grep "" will skip the empty lines.

Note:

  1. Using IFS= keeps any line indentation intact.

  2. You should almost always use the -r option with read.

  3. File without a newline at the end isn't a standard unix text file.

Solution 4:

Instead of read, try to use GNU Coreutils like tee, cat, etc.

from stdin

readvalue=$(tee)
echo $readvalue

from file

readvalue=$(cat filename)
echo $readvalue