如果您打开一个文件,并且该文件的最后一行末尾vim
没有“no” ,则编辑器会将其报告为.EOL
[noeol]
我怎样才能确定这个前打开它在vim
? (我可以发出命令来确定这一点吗?)
答案1
tail -c 1
输出其输入的最后一个字符(更准确地说,最后一个字节)。
命令替换会去掉尾随的换行符,$(tail -c 1 <…)
因此空的如果文件的最后一个字符是换行符。如果最后一个字符是空字节(在大多数 shell 中),它也为空,但文本文件没有空字节。
请记住,空文件不需要额外的换行符。
if [ ! -s "$filename" ]; then
echo "$filename is empty"
elif [ -z "$(tail -c 1 <"$filename")" ]; then
echo "$filename ends with a newline or with a null byte"
else
echo "$filename does not end with a newline nor with a null byte"
fi
答案2
创建一个仅包含换行符的文件,然后将其与文件的最后一个字节进行比较:
printf '\n' > newline_only
tail -c 1 your_file | cmp -s newline_only -
我以前基本上cmp -s
是cmp
沉默的。退出状态0
表示在 的最末尾有一个换行符your_file
。
如果your_file
为空,则退出状态将为1
。您可能想破例并参与0
这种情况。如果是这样,前置cmp
通过其标准输入获取的内容的换行符:
( printf '\n'; tail -c 1 your_file ) | cmp -s newline_only -
# or
cat newline_only your_file | tail -c 1 | cmp -s newline_only -
# or better
<your_file cat newline_only - | tail -c 1 | cmp -s newline_only -
your_file
最后一个稍微好一些,因为如果不存在、无法读取等,它将返回非零退出状态。如果我是你,我会想要这个。尽管 ifyour_file
实际上是一个目录 then cat
,tail
并且cmp
将会运行,并且您可能会收到;0
的投诉;cat
或者可能不会,请看这个:目录何时停止作为文件读取?)。因此你可能想要一些额外的逻辑或选项(例如set -o pipefail
在 Bash 中)。
笔记:
在某些 shell 中,您可以使用进程替换来避免创建
newline_only
文件。它将是这样的:# e.g. in Bash < your_file cat <(printf '\n') - | tail -c 1 | cmp -s <(printf '\n') -
tail
从管道读取无法查找。cat
需要阅读全文your_file
,然后tail
才能完成其工作。tail -c 1 your_file
或者<your_file tail -c 1
可能足够聪明,能够向内寻求your_file
。如果您测试一个或几个,这应该可以忽略不计小的文件虽然。- 这个其他解决方案可能会表现更好:它不创建文件;它不会通过管道进入
tail
;它不会产卵cmp
;它使用的[
是许多 shell 中的内置函数。
答案3
这其实跟没有什么关系vim
。差不多就是你想要的
tail -c 1 file
获取文件的最后一个字符。