Cit*_*ght 4 grep character-encoding cat
我有一个 300 行的文件,文件中的^@
每个字符之间都有字符。
(出于安全原因,我无法发布全部内容,所以我只粘贴了第一行)
[mercury@app01 ftp_logs]$ cat cl.txt
2015-01-22 03:00:01; local;
Run Code Online (Sandbox Code Playgroud)
现在,当我vi
打开文件时,我看到以下相同的内容:
2^@0^@1^@5^@-^@0^@1^@-^@2^@2^@ ^@0^@3^@:^@0^@0^@:^@0^@1^@;^@ ^@l^@o^@c^@a^@l^@;^@
由于cat
不显示^@
字符,自然我认为对某个字符串进行 grep 可以在cat
.
[mercury@app01 ftp_logs]$ cat cl.txt
2015-01-22 03:00:01; local;
[mercury@app01 ftp_logs]$ cat cl.txt | grep local
[mercury@app01 ftp_logs]$
Run Code Online (Sandbox Code Playgroud)
用 替换空字节后sed
,文件现在可以读取vi
并grep
从 返回结果cat
。
[mercury@app01 ftp_logs]$ sed -i 's/\x0//g' cl.txt
[mercury@app01 ftp_logs]$ cat cl.txt | grep local
2015-01-22 03:00:01; local;
[mercury@app01 ftp_logs]
Run Code Online (Sandbox Code Playgroud)
问题:
1) 为什么grep
在替换空字节之前不起作用,因为没有显示空字节。这是否意味着即使没有显示在终端中也grep
看到了^@
字符?
2)这让我想知道是否建议使用cat -v
或vi
读取生产服务器上的文件,因为cat
似乎隐藏东西很好?
3) 有问题的文件是从 Windows 机器自动生成的文件。在什么情况下会^@
进入文件。
该文件的格式可能是小端 UTF-16。Windows 上的一些应用程序似乎默认为这个,并且它会导致很多可移植性问题。
vi
将 ASCII-Nul(数字为零)值字节表示为“^@”(控制-At)。您实际上可以vim
使用 control-shift-@ 和弦输入零值字节。
grep
必须查看 ACII-Nul 字节,而不是将文件解释为 UTF-16,然后查看“2”或“0”等的 Unicode 代码点。我在 GNUgrep
手册页中没有看到用于处理 UTF-anything 的选项。
cat
不显示 ASCII-Nul 字节,有问题的终端仿真器会显示它们,但无论您使用什么终端仿真器,都会忽略它们。如果您使用cat cl.txt | od -x
或更好的 ,cat cl.txt | xxd
您将在cat
. 如果你看到像 'ffef' 或 'efff' 这样的东西作为文件的前两个字节,那是微软违反所有常识颁布的“字节顺序标记”。
我不确定推荐什么来将 UTF-16 音译为 ASCII 或 UTF-8,iconv
也许,但我从未使用过它。