在Linux - check if there is an empty line at the end of a file中,有些帖子使用[[ ]]
和==
来比较字符。
我想编写一个单行命令来检测EOF中是否没有换行符,而我遇到了这个小问题。
在echo
的输出中,末尾有\n
。
$ echo echo | od -c
0000000 e c h o \n
0000005
$ echo -n echo | od -c
0000000 e c h o
0000004
如果我将[[ ]]
和==
放在一起,那么我不会得到预期的输出。
$ [[ `echo echo | tail -c1` == "\n" ]] && echo true
$ [[ `echo echo | tail -c1` != "\n" ]] && echo true
true
$ [[ `echo -n echo | tail -c1` != "\n" ]] && echo true
true
如od -c
所示,echo echo | tail -c1
的输出为\n
,而[[ "\n" == "\n" ]] && true
将返回true
,所以我希望第一个命令给出{{ 1}}。但是,为什么将它评估为空字符串?
感谢阅读!
答案 0 :(得分:2)
Bash Reference Manual中已明确指出:
Bash通过在子shell环境中执行命令并将命令替换替换为命令的标准输出,并删除所有尾随换行符来执行扩展。
打开-x
标志以查看清楚的情况:
$ set -x
$ [[ `echo echo | tail -c 1` == '\n' ]]
++ tail -c 1
++ echo echo
+ [[ '' == \\\n ]]
$
$ echo "$(echo)"
++ echo
+ echo ''
此外,即使未修剪尾随的换行符,您的比较也不会返回true,因为'\n'
不是换行符,而实际上是反斜杠,后跟字母n
。您应该使用$'\n'
来获取实际的换行符。
答案 1 :(得分:1)
对于解决方案,您可以使用以下内容:
$ printf 'test\n' | perl -0777ne'exit(/\n\z/?0:1)' || echo "Missing line feed" >&2
$ printf 'test' | perl -0777ne'exit(/\n\z/?0:1)' || echo "Missing line feed" >&2
Missing line feed
或
$ printf 'test\n' | perl -0777ne'die("Missing line feed\n") if !/\n\z/'
$ printf 'test' | perl -0777ne'die("Missing line feed\n") if !/\n\z/'
Missing line feed