字元在 vi 中可見,但在 cat 中不可見。
我有一個 300 行
^@
的文件,文件中的每個字元之間都有字元。(出於安全原因,我無法發布全部內容,所以我只粘貼第一行)
[mercury@app01 ftp_logs]$ cat cl.txt 2015-01-22 03:00:01; local;
現在,當我
vi
打開文件時,我看到的內容與以下相同:
2^@0^@1^@5^@-^@0^@1^@-^@2^@2^@ ^@0^@3^@:^@0^@0^@:^@0^@1^@;^@ ^@l^@o^@c^@a^@l^@;^@
由於
cat
不顯示^@
字元,自然我認為 grepping 某個字元串可以在 中工作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]$
用 替換空字節後
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]
問題:
grep
1)鑑於沒有顯示空字節,為什麼在替換空字節之前不起作用。這是否意味著grep
看到^@
字元,即使它沒有顯示在終端中?2)這讓我想知道是否建議在生產伺服器上使用
cat -v
或vi
讀取文件,因為cat
它似乎擅長隱藏東西?
- 有問題的文件是從 Windows 機器自動生成的文件。在什麼情況下會
^@
進入文件。
文件的格式可能是 little-endian UTF-16。Windows 上的某些應用程序似乎預設使用此功能,這會導致很多便攜性問題。
vi
將 ASCII-Nul(數字為零)值字節表示為“^@”(控制-At)。您實際上可以vim
使用 control-shift-@ 和弦輸入零值字節。
grep
必須看到 ACII-Nul 字節,而不是將文件解釋為 UTF-16,然後看到 ‘2’ 或 ‘0’ 或其他的 Unicode 程式碼點。我在 GNU 手冊頁中沒有看到grep
使它處理 UTF-anything 的選項。
cat
不顯示 ASCII-Nul btyes,有問題的終端仿真器會顯示它們,但是您使用的任何終端仿真器都會忽略它們。如果您使用cat cl.txt | od -x
或更好,cat cl.txt | xxd
您將在 的輸出中看到 ASCII-Nul 字節cat
。如果您在文件的前兩個字節中看到類似 ‘ffef’ 或 ’efff’ 之類的東西,那麼這些就是 Microsoft 頒布的違反所有常識的“字節順序標記”。我不確定推薦什麼將 UTF-16 音譯為 ASCII 或 UTF-8,
iconv
也許,但我從未使用過它。