如何找到最后没有空行的文件?

jcu*_*bic 12 search files newlines

我在当前目录的子目录中有文件,最后可能有也可能没有新行;如何找到最后没有换行符的文件?

我试过这个:

find . -name '*.styl' | while read file; do
    awk 'END{print}' $file | grep -E '^$' > /dev/null || echo $file;
done
Run Code Online (Sandbox Code Playgroud)

但它不起作用。 awk 'END{print}' $file在空的新行之前打印该行,与tail -n 1 $file.

Sté*_*las 15

澄清一下,LF(又名\n或换行符)字符是行分隔符,而不是行分隔符。除非以换行符终止,否则一行不会结束。仅包含的文件a\nb不是有效的文本文件,因为它在最后一行之后包含字符。对于仅包含a. 一个包含文件a\n中包含一个非空行。

因此,以至少一个空行结尾的文件以两个换行符结尾或包含一个换行符。

如果:

 tail -c 2 file | od -An -vtc
Run Code Online (Sandbox Code Playgroud)

输出\nor \n \n,则文件至少包含一个尾随空行。如果它什么都不输出,那么这是一个空文件,如果它输出<anything-but-\0> \n,那么它以非空行结束。其他任何东西,它都不是文本文件。

现在,要使用它来查找以空行结尾的文件,这是有效的(特别是对于大文件),因为它只读取文件的最后两个字节,但首先输出不容易以编程方式解析,特别是考虑到它是从一个实现od到下一个实现不一致,我们需要为每个文件运行一个tail和一个od

find . -type f -size +0 -exec gawk '
  ENDFILE{if ($0 == "") print FILENAME}' {} +
Run Code Online (Sandbox Code Playgroud)

(查找以空行结尾的文件)将运行尽可能少的命令,但这意味着读取所有文件的完整内容。

理想情况下,您需要一个可以自行读取文件末尾的 shell。

zsh

zmodload zsh/system
for f (**/*(D.L+0)) {
  {
    sysseek -w end -2
    sysread
    [[ $REPLY = $'\n' || $REPLY = $'\n\n' ]] && print -r -- $f
  } < $f
}
Run Code Online (Sandbox Code Playgroud)


don*_*sti 6

gnu sed和壳状zsh(或bashshopt -s globstar):

sed -ns '${/./F}' ./**/*.styl
Run Code Online (Sandbox Code Playgroud)

这会检查每个文件的最后一行是否不为空,如果是,则打印文件名。
如果你想要相反的(如果最后一行为空,则打印文件名)只需替换/.//^$/