bash 如何检测文件以换行符结尾?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38746/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 20:27:57  来源:igfitidea点击:

How to detect file ends in newline?

svnbashtext-files

提问by grom

Over at Can you modify text files when committing to subversion?Grantsuggested that I block commits instead.

提交到 Subversion 时,您可以修改文本文件吗?Grant建议我改为阻止提交。

However I don't know how to check a file ends with a newline. How can you detect that the file ends with a newline?

但是我不知道如何检查文件是否以换行符结尾。如何检测文件是否以换行符结尾?

采纳答案by 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:

@Konrad:tail 不返回空行。我制作了一个文件,其中包含一些不以换行符结尾的文本和一个以换行符结尾的文件。这是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:

虽然我发现 tail 有最后一个字节选项。所以我将你的脚本修改为:

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

回答by FelipeC

Or even simpler:

或者更简单:

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

But if you want a more robust check:

但是,如果您想要更强大的检查:

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

回答by Steve Kehlet

Here is a useful bash function:

这是一个有用的 bash 函数:

function file_ends_with_newline() {
    [[ $(tail -c1 "" | 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

回答by KarolDepka

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.

所以 wc 计算换行符的数量,这在我们的例子中很好。oneliner 根据文件末尾是否存在换行符打印 0 或 1。

回答by bstark

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;
}

回答by Konrad Rudolph

Using only bash:

仅使用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

tail 不返回空行

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

该死。我的测试文件不是\n\n\n. 显然vim不能创建不以\n(?)结尾的文件。无论如何,只要“获取最后一个字节”选项有效,一切都会好起来的。

回答by Koichi Nakashima

The readcommand can not read a line without newline.

read命令无法读取没有换行符的行。

if tail -c 1 "" | read -r line; then
  echo "newline"
fi

Another answer.

另一个答案。

if [ $(tail -c 1 "" | od -An -b) = 012 ]; then
  echo "newline"
fi

回答by Nicolae Iotu

I'm coming up with a correction to my own answer.

我想更正我自己的答案。

Below should work in all cases with no failures:

以下应该在所有情况下都没有失败:

nl=$(printf '2')
nls=$(wc -l "${target_file}")
lastlinecount=${nls%% *}
lastlinecount=$((lastlinecount+1))
lastline=$(sed ${lastlinecount}' !d' "${target_file}")
if [ "${lastline}" = "${nl}" ]; then
    echo "${target_file} ends with a new line!"
else
    echo "${target_file} does NOT end with a new line!"
fi

回答by thanos.a

You can get the last character of the file using tail -c 1.

您可以使用tail -c 1.

   my_file="/path/to/my/file"

   if [[ $(tail -c 1 "$my_file") != "" ]]; then
      echo "File doesn't end with a new line: $my_file"
   fi