How to detect file ends in newline?

眉间皱痕 提交于 2019-11-29 03:19:33
grom

@Konrad: tail does not return an empty line. I made a file that has some text that doesn't end in newline and a file that does. Here is the output from tail:

$ cat test_no_newline.txt
this file doesn't end in newline$ 

$ cat test_with_newline.txt
this file ends in newline
$

Though I found that tail has get last byte option. So I modified your script to:

#!/bin/sh
c=`tail -c 1 $1`
if [ "$c" != "" ]; then echo "no newline"; fi

Or even simpler:

#!/bin/sh
test "$(tail -c 1 "$1")" && echo "no newline at eof: '$1'"

But if you want a more robust check:

test "$(tail -c 1 "$1" | wc -l)" -eq 0 && echo "no newline at eof: '$1'"

Here is a useful bash function:

function file_ends_with_newline() {
    [[ $(tail -c1 "$1" | wc -l) -gt 0 ]]
}

You can use it like:

if ! file_ends_with_newline myfile.txt
then
    echo "" >> myfile.txt
fi
# continue with other stuff that assumes myfile.txt ends with a newline

You could use something like this as your pre-commit script:

#! /usr/bin/perl

while (<>) {
    $last = $_;
}

if (! ($last =~ m/\n$/)) {
    print STDERR "File doesn't end with \\n!\n";
    exit 1;
}

Worked for me:

tail -n 1 /path/to/newline_at_end.txt | wc --lines
# according to "man wc" : --lines - print the newline counts

So wc counts number of newline chars, which is good in our case. The oneliner prints either 0 or 1 according to presence of newline at the end of the file.

Using only bash:

x=`tail -n 1 your_textfile`
if [ "$x" == "" ]; then echo "empty line"; fi

(Take care to copy the whitespaces correctly!)

@grom:

tail does not return an empty line

Damn. My test file didn't end on \n but on \n\n. Apparently vim can't create files that don't end on \n (?). Anyway, as long as the “get last byte” option works, all's well.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!