I have files in subdirectories of the current directory that may or may not have new lines at the end; how can I find files that don't have a newline at the end?
I've tried this:
find . -name '*.styl' | while read file; do
awk 'END{print}' $file | grep -E '^$' > /dev/null || echo $file;
done
but it doesn't work. awk 'END{print}' $file
prints the line before an empty new line, the same as tail -n 1 $file
.
Best Answer
To clarify, the LF (aka
\n
or newline) character is the line delimiter, it's not the line separator. A line is not finished unless it's terminated by a newline character. A file that only containsa\nb
is not a valid text file because it contains characters after the last line. Same for a file that contains onlya
. A file that containsa\n
contains one non-empty line.So a file that ends with at least one empty line ends with two newline characters or contains a single newline character.
If:
Outputs
\n
or\n \n
, then the file contains at least one trailing empty line. If it outputs nothing, then that's an empty file, if it outputs<anything-but-\0> \n
, then it ends in a non-empty line. Anything else, it's not a text file.Now, to use that to find files that end in an empty line, OK that's efficient (especially for large files) in that it only reads the last two bytes of the files, but first the output is not easily parsable programmatically especially considering that it's not consistent from one implementation of
od
to the next, and we'd need to run onetail
and oneod
per file.(to find files ending in an empty line) would run as few commands as possible but would mean reading the full content of all files.
Ideally, you'd need a shell that can read the end of a file by itself.
With
zsh
: