
^@
ファイル内の各文字の間に文字を含む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
文字が表示されないので、^@
当然、どの文字列のgrepingがで動作すると思ったが、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]$
nullバイトをに置き換えた後、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]
質問:
1)grep
NULLバイトが表示されないため、NULLバイトを交換する前に機能しないのはなぜですか?これはgrep
、これらの文字が端末に表示されなくても表示されることを意味しますか?^@
2) ファイルをかなり隠すようなので、本番サーバーでファイルを使用またはcat -v
読み取ることをお勧めします。vi
cat
3)ファイルはWindowsコンピュータで自動的に作成されたファイルです。どのような状況で^@
ファイルが入力されますか?
答え1
ファイル形式はリトルエンディアンUTF-16です。 Windows の一部のアプリケーションは既定でこれを行うように見え、これにより多くの移植性の問題が発生します。
vi
ASCII-Nul(数値 0) 値バイトを "^@"(control-At) で表します。実際、vim
ゼロ値バイトを入力するには、control-shift-@ コードを使用できます。
grep
ファイルをUTF-16として解釈してから、「2」または「0」などのUnicodeコードポイントを見るのではなく、ACII-Nulバイトを見てください。 GNUのマニュアルページにはgrep
UTFを処理するオプションはありません。
cat
ASCII-Nul btyは表示されず、問題の端末エミュレータはそれを表示しますが、使用する端末エミュレータはそれを無視します。cat cl.txt | od -x
以上を使用すると、cat cl.txt | xxd
出力にASCII-Nulバイトが表示されますcat
。ファイルの最初の2バイトに「ffef」や「efff」などの内容が表示される場合、これは常識に反してMicrosoftが制定した「バイト順表示」です。
UTF-16をASCIIまたはUTF-8に翻訳するために何をお勧めするのかわかりませんが、iconv
一度も試したことはありません。
答え2
はい、役割を
grep
変えてください^@
。cat
文字が端末に印刷されているが見えない文字です。これらの文字が見えないとしても、その文字が存在しないという意味ではありません。あなたの選択/好みは、あなたのニーズに最も適したものが何であるかによって異なります。ただし、これにより
vi
ファイルが変更される可能性があることに注意してください。^@
生まれた性格ではない。 Windowsプログラムはこれらの文字を積極的にここに配置します。理由を調べるには、プログラマーに尋ねる必要があります。ほとんどの場合、Windowsプログラムでは文字の幅が16ビットであると仮定しますが、Unixシステムでは文字の幅が8ビットであると仮定します。
答え3
私はかつて同じ問題を経験しました。
vi
ファイル文字セットについて学びます。
使用する場合
file c1.txt
UTF-8ファイルかISOファイルかを確認できます。
その後、変換ユーティリティを使用して変換できます。
echo file iso-8859-1 is converted to UTF in order to be emailed
iconv -f 'iso-8859-1' -t UTF-8 $MESGFILE >> $MESGENVIADO