文字化けの原因調査、シェルスクリプトが改行コードの違いで誤作動するケース、あるいは外部から受け取ったファイルに予期しないバイトが混入していないかを確かめたい場面があります。cat や less では制御文字は見えません。バイト列を直接確認できるツールを使うのが最短経路です。
バイト単位の確認が必要になる場面
ある運用現場では、外部から受け取った CSV ファイルを Python スクリプトで処理しようとすると毎回エラーになるという問題を抱えていました。file コマンドでは「UTF-8」と表示されるのに、実際には BOM(Byte Order Mark、先頭3バイト EF BB BF)が付いていたのが原因でした。cat では BOM は表示されず、バイト列を直接確認して初めて判明したケースです。
このほか、以下のような場面でバイト単位の確認が役立ちます。
- Windows で作成したファイルを Linux で処理すると改行コードが CRLF(
\r\n)になっており、シェルスクリプトが誤作動する - 設定ファイルにタブと空白が混在していて、インデント依存のパーサーが失敗する
- ログファイルや受信データにヌルバイト(
\x00)が混入している - バイナリプロトコルのデバッグでパケット内容を目視したい
od で制御文字と改行コードを素早く確認する
od(octal dump)はほぼすべての Linux 環境に標準搭載されています。デフォルトは8進数表示ですが、-c オプションを付けると文字と制御コードを人間が読みやすい形式で表示でき、改行コードの確認に最も手軽です。
# 文字+制御コードで表示(改行コード確認に最適)
od -c ip_list.txt
# 16進数で表示
od -x ip_list.txt
# 1バイトずつ16進数・オフセットなし
od -An -tx1 ip_list.txt
実行例(ip_list.txt に複数の IP アドレスが1行ずつ格納されている場合):
$ od -c ip_list.txt
0000000 1 9 2 . 1 6 8 . 1 . 1 \n 1 9 2 .
0000020 1 6 8 . 1 . 3 3 \n 1 2 9 . 1 8 6
0000040 . 1 . 0 5 \n \n
0000047
左端の数字はオフセット(8進数)です。各行末に \n(LF)が見えます。Windows 由来のファイルであれば \r\n と並んで表示されるため、改行コードを視覚的に確認する最速の手段として使えます。
hexdump と xxd で16進数ダンプを読む
文字コードの診断では、バイト値を16進数で直接確認する必要があります。hexdump と xxd の2つが代表的なツールです。
hexdump の使い方
オプションなしのデフォルト表示はリトルエンディアンの2バイト単位で見づらいため、実務では -C オプションが定番です。左に16進数、右に ASCII が並ぶ標準的な hexdump 形式になります。
# 読みやすい標準形式(-C オプション推奨)
hexdump -C ip_list.txt
# 先頭 64 バイトだけ確認
hexdump -C -n 64 ip_list.txt
$ hexdump -C ip_list.txt
00000000 31 39 32 2e 31 36 38 2e 31 2e 31 0a 31 39 32 2e |192.168.1.1.192.|
00000010 31 36 38 2e 31 2e 33 33 0a 31 32 39 2e 31 38 36 |168.1.33.129.186|
00000020 2e 31 2e 30 35 0a 0a |.1.05..|
00000027
0a が LF、0d が CR です。0d 0a が連続していれば CRLF と判断できます。
xxd の使い方(バイナリ編集にも対応)
xxd は vim に同梱されており、多くのディストリビューションで利用できます。出力形式は hexdump -C に近いですが、16進数ダンプを編集してバイナリファイルに書き戻す「ラウンドトリップ編集」が可能な点が強みです。また -p オプションでバイト列だけを連続出力できるため、grep との組み合わせにも向いています。
# 基本表示
xxd ip_list.txt
# 先頭 32 バイトだけ表示
xxd -l 32 ip_list.txt
# 連続した16進数文字列で出力(grep と組み合わせやすい)
xxd -p ip_list.txt
# UTF-8 BOM 確認(先頭3バイトだけ取り出す)
xxd -l 3 suspicious_file.txt
$ xxd ip_list.txt
00000000: 3139 322e 3136 382e 312e 310a 3139 322e 192.168.1.1.192.
00000010: 3136 382e 312e 3333 0a31 3239 2e31 3836 168.1.33.129.186
00000020: 2e31 2e30 350a 0a .1.05..
実務でよく使う診断パターン
UTF-8 BOM を検出する
UTF-8 BOM は先頭3バイトが EF BB BF です。Python や一部のシェルスクリプトはこのバイト列をデータとして扱ってしまいエラーになります。
# BOM の有無を確認
xxd -l 3 target.txt
# BOM がある場合の出力例
# 00000000: efbb bf ...
# BOM を取り除く(元ファイルを上書きするため必ずバックアップを)
cp target.txt target.txt.bak
sed -i '1s/^\xEF\xBB\xBF//' target.txt
改行コードを判別して修正する(CRLF vs LF)
# \r\n(0d 0a)が含まれているか確認
xxd target.sh | grep '0d.0a\|0d 0a'
# od で制御文字として確認
od -c target.sh | grep '\\r'
# CRLF → LF に変換(dos2unix が使える環境)
dos2unix target.sh
# dos2unix がない場合
sed -i 's/\r//' target.sh
\r が含まれているシェルスクリプトは実行時に「command not found」のようなエラーが出ることがあります。原因が掴めないまま長時間調査が続くケースも多く、まずバイト列を確認する習慣を持つと早期解決につながります。
ヌルバイト・制御文字を検出する
# ヌルバイト(00)が何バイト含まれるか数える
xxd -p target_file | grep -o '00' | wc -l
# grep でヌルバイトを含む行を検出
grep -Pc '\x00' target_file && echo "null byte found"
# バイナリファイルかどうかを簡易判定
file target_file
3つのツールの使い分けまとめ
目的に合わせてツールを選ぶと作業効率が上がります。
- od -c:改行コードや制御文字を素早く目視したいとき。標準搭載で確実に使えるため、環境を選ばない場面に最適。
- hexdump -C:16進数と ASCII を並べて詳細確認したいとき。バイナリプロトコル解析やファイル先頭のマジックバイト確認に向く。
- xxd:BOM 検出・文字コード診断・バイナリ編集まで含めた用途。-p で grep と組み合わせやすく、実務で最も出番が多い。
いずれも読み取り目的で使う分にはファイルを変更しませんが、sed -i や xxd -r(逆変換による書き戻し)で実際にファイルを変更する際は、必ず事前にバックアップを取ってください。本番環境のファイルに対してバイト単位の編集を行うと、元に戻せないデータ破損につながる可能性があります。
「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。
ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。
>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)
※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。
