Respect last line if it's not terminated with a new line char (\n) when using read Respect last line if it's not terminated with a new line char (\n) when using read shell shell

Respect last line if it's not terminated with a new line char (\n) when using read


read does, in fact, read an unterminated line into the assigned var ($REPLY by default). It also returns false on such a line, which just means ‘end of file’; directly using its return value in the classic while loop thus skips that one last line. If you change the loop logic slightly, you can process non-new line terminated files correctly, without need for prior sanitisation, with read:

while read -r || [[ -n "$REPLY" ]]; do    # your processing of $REPLY heredone < "/path/to/file"

Note this is much faster than solutions relying on externals.

Hat tip to Gordon Davisson for improving the loop logic.


POSIX requires any line in a file have a newline character at the end to denote it is a line. But this site offers a solution to exactly the scenario you are describing. Final product is this chunklet.

newline=''lastline=$(tail -n 1 file; echo x); lastline=${lastline%x}[ "${lastline#"${lastline%?}"}" != "$newline" ] && echo >> file# Now file is sane; do our normal processing here...


If you must use read, try this:

awk '{ print $0}' foo | while read line; do    echo the line is $linedone

as awk seems to recognize lines even without the newline char