LinuxサーバーにWindowsや旧システムからファイルを持ち込んだとき、ターミナルや処理スクリプトで文字化けが発生するケースはよくあります。原因はほぼ確実に文字コード(エンコーディング)の不一致です。nkfやiconvを使えば、判定から変換まで数コマンドで片付きます。
まず結論:2ステップで文字化けは解消できる
手順は「判定→変換」の2ステップです。変換先は現代のLinux環境ではUTF-8一択と考えて問題ありません。
# ステップ1:ファイルの文字コードを確認する
nkf --guess moji.txt
# 例: Shift_JIS (LF)
# ステップ2:UTF-8 に変換して別ファイルに保存する
nkf -w moji.txt > moji_utf8.txt
元ファイルを直接上書きする場合は --overwrite オプションを使いますが、その場合はかならず事前にバックアップを取ってください。上書き後の復元はできません。
ファイルの文字コードを正確に判定する
変換元の文字コードを間違えると二重変換になり、より深刻な文字化けを引き起こします。判定は変換前の必須ステップです。
nkf –guess(日本語判定に最も信頼性が高い)
nkf --guess moji.txt
# 出力例: Shift_JIS (LF)
# 出力例: EUC-JP (LF)
# 出力例: UTF-8 (LF)
nkf は日本語エンコーディング判定に特化しており、Shift-JIS / EUC-JP / JIS / UTF-8 を区別して返してくれます。インストールされていない場合は以下でインストールできます。
# Debian / Ubuntu 系
sudo apt install nkf
# RHEL / Rocky / AlmaLinux / Fedora 系
sudo dnf install nkf
file -i(追加インストール不要だが判定精度は低め)
file -i moji.txt
# 出力例: moji.txt: text/plain; charset=iso-2022-jp
file コマンドは標準搭載で便利ですが、日本語テキストを unknown-8bit と返す場合があります。日本語ファイルの判定には nkf --guess を優先してください。
nkfで文字コードを変換する
日本語ファイルを扱う実務では nkf が最も手軽です。変換と出力を1コマンドで処理できます。
主なオプションの対応は次のとおりです。
-w:UTF-8 に変換して出力(現代の標準)-s:Shift-JIS に変換して出力-e:EUC-JP に変換して出力-j:JIS に変換して出力--guess:変換せず文字コードを判定して表示
# Shift-JIS のファイルを UTF-8 に変換して別ファイルに保存
nkf -w moji_sjis.txt > moji_utf8.txt
# 元ファイルを直接 UTF-8 に上書き変換(事前バックアップを必ず取ること)
cp moji.txt moji.txt.bak
nkf -w --overwrite moji.txt
# EUC-JP を UTF-8 に変換して別ファイルへ
nkf -w moji_euc.txt > moji_utf8.txt
iconvで変換する(標準ツールを使いたい場合)
iconv はLinuxに標準搭載されているため、追加インストールなしで使えます。CI/CDパイプラインやDockerイメージなど nkf を入れたくない環境に適しています。
# Shift-JIS → UTF-8
iconv -f SHIFT_JIS -t UTF-8 input.txt -o output.txt
# EUC-JP → UTF-8
iconv -f EUC-JP -t UTF-8 input.txt -o output.txt
# UTF-8 → Shift-JIS(Windows向けに戻す場合)
iconv -f UTF-8 -t SHIFT_JIS input.txt -o output.txt
-f が変換元(from)、-t が変換先(to)、-o が出力先ファイルです。-o を省略すると標準出力に流れるため、リダイレクトで受け取ることもできます。
変換できない文字が含まれているとエラーで止まる場合があります。-c オプションで変換できない文字をスキップできますが、その文字は出力から消えます。重要なファイルでは使用前に内容を確認してください。
# 変換不能な文字をスキップして続行(文字が消える点に注意)
iconv -f SHIFT_JIS -t UTF-8 -c input.txt -o output.txt
実務でよく引っかかるケース:BOM付きUTF-8
ある運用現場では、Windows側でUTF-8として保存したCSVをLinuxスクリプトで処理したところ、先頭行のヘッダー比較が常に失敗するという問題が発生しました。原因はWindowsが付加したBOM(Byte Order Mark)でした。BOMはファイル先頭に見えない3バイト(0xEF 0xBB 0xBF)として存在し、Linuxツールがそのままデータとして読んでしまいます。
# BOMの有無を確認する
file -i moji.txt
# charset=utf-8 → BOMなし
# charset=utf-8-bom → BOMあり(Windowsで作成された可能性が高い)
# nkfでBOMを除去しながらUTF-8に変換
nkf -w moji_bom.txt > moji_nobom.txt
# iconvの場合:UTF-8-BOM を指定して変換
iconv -f UTF-8-BOM -t UTF-8 moji_bom.txt -o moji_nobom.txt
WindowsからのCSVやテキストログでスクリプトが謎の動作をするときは、まずBOMを疑うと解決が早いです。
複数ファイルをまとめてUTF-8に変換する
旧システムからファイルを一括移行する際など、大量ファイルを一気に変換したい場面があります。find と組み合わせる方法と、安全のため変換先ディレクトリを分ける方法の両方を示します。
# 方法1:その場で上書き変換(作業前にディレクトリごとバックアップを取ること)
find . -name "*.txt" -exec nkf -w --overwrite {} \;
# 方法2:変換先ディレクトリに別名で保存する(元ファイルを残す安全な方法)
mkdir -p converted
find . -maxdepth 1 -name "*.txt" | while IFS= read -r f; do
nkf -w "$f" > "converted/$(basename "$f")"
done
方法1は手軽ですが失敗時に元ファイルが残りません。本番データを扱う場合は方法2のように変換先を分けるほうが安全です。変換後に nkf --guess で数ファイルを抽出確認し、すべて UTF-8 になっていることを確認してから元ファイルを削除する運用をおすすめします。
「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。
ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。
>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)
※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。
