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)
用gnu sed和壳状zsh(或bash带shopt -s globstar):
sed -ns '${/./F}' ./**/*.styl
Run Code Online (Sandbox Code Playgroud)
这会检查每个文件的最后一行是否不为空,如果是,则打印文件名。
如果你想要相反的(如果最后一行为空,则打印文件名)只需替换/./为/^$/