我正在使用一台 Windows-10 计算机,使用 WSL。
我正在调查由 C# 应用程序生成的日志文件NLog
。我期望日志条目会出现在整个文件的各个位置,但我看到以下内容:
Linux prompt> grep "geen mengcontainer" logfile.log
2023-03-07 07:25:08.7971 | Warn | ... | geen mengcontainer.
2023-03-07 07:25:09.8285 | Warn | ... | geen mengcontainer.
2023-03-07 07:25:10.8754 | Warn | ... | geen mengcontainer.
Binary file logfile.log matches
如您所见,在 07:25:10 之后,grep
停止了,尽管文件在当天的剩余时间内继续运行。似乎有一些字符表明grep
该文件不是文本文件,而是二进制文件,导致grep
停止工作。
有关该文件的更多信息:
Linux prompt>file logfile.log
logfile.log: ASCII text, with CRLF line terminators
有关我的 Linux WSL 安装的更多信息:
Linux prompt>uname -a
Linux ComputerName 4.4.0-19041-Microsoft
#2311-Microsoft Tue Nov 08 17:09:00 PST 2022
x86_64 x86_64 x86_64 GNU/Linux
Linux prompt> cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
VERSION_ID="20.04"
...
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
关于我的安装的更多信息grep
:
Linux prompt> grep --version
grep (GNU grep) 3.4
我能做些什么?
- 有人知道如何查找和替换负责
grep
停止过滤的字符吗? - 有人知道我可以添加哪些额外的参数或开关
grep
以便不停止过滤吗? - 有人知道
grep
没有这种行为的版本吗?(请考虑到apt update
在我的环境中它不起作用)
提前致谢
答案1
用于grep -a
强制将文件始终视为文本。
“二进制文件”检测对代码页敏感 – 如果 grep 像在 Linux 上一样需要 UTF-8 输入,它实际上会将“ANSI”(Windows-125x、ISO 8859-x)编码的文本文件检测为二进制文件。在“C”语言环境中使用LC_CTYPE=C grep
或运行 grepLC_ALL=C grep
也可以避免此问题。
(此外,“文件”关于输入为“ASCII”的说法完全基于对文件内初始字节的快速查看;它实际上并没有扫描整个文件,而“grep”当然会扫描整个文件。)
通常整个文件都采用相同的编码(即所有文件都可能是非 UTF-8),因此查找有问题的字符的一个简单方法是搜索非 ASCII 字节(LC_ALL=C
可能被需要):
grep -a -P -n --color '[^\x00-\x7F]' logfile.log
perl -ne 'print "Line $.:\t$_" if /[^\0-\177]/' < logfile.log
这也将突出显示有问题的字节:
perl -ne 'print "Line $.:\t$_" if s/[^\0-\177]/sprintf"\e[41m<%02X>\e[m",ord$&/ge' < logfile.log
如果文件是除了一些奇怪的行之外,有效的 UTF-8 编码,使用类似的方法打印 UTF-8 解码失败的行:
perl -MEncode -ne 'print "Line $.:\t$_" if !eval{decode("UTF-8", $_, Encode::FB_CROAK)}' < logfile.log