Grep

字元在 vi 中可見,但在 cat 中不可見。

  • January 24, 2022

我有一個 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,文件現在可以讀取vigrepcat.

[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]

問題:

grep1)鑑於沒有顯示空字節,為什麼在替換空字節之前不起作用。這是否意味著grep看到^@字元,即使它沒有顯示在終端中?

2)這讓我想知道是否建議在生產伺服器上使用cat -vvi讀取文件,因為cat它似乎擅長隱藏東西?

  1. 有問題的文件是從 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也許,但我從未使用過它。

引用自:https://unix.stackexchange.com/questions/183089