稀に文字コードの混在したファイル群を扱う時があります。こういった時にそのままファイル全ての文字コードを変換すると二重に変換を行ってしまい文字化けすることがあります。
これの対策として次のような特定の文字コードであれば放置し、そうでないならば変換するというスクリプトを使えます。実際のコード例が次です。
#!/bin/bash
# 引数(ファイル名)が指定されているかチェック
if [ "$#" -ne 1 ]; then
echo "使用法: $0 ファイル名"
exit 1
fi
# ファイル名を変数に格納
file="$1"
# fileコマンドでエンコーディングを確認し、小文字に統一
encoding=$(file -bi "$file" | sed -e 's/.*charset=//' | tr '[:upper:]' '[:lower:]')
# エンコーディングがutf-8またはasciiであれば、そのままのファイルパスを出力
if [ "$encoding" = "utf-8" ] || [ "$encoding" = "us-ascii" ]; then
echo "$file"
else
# SJISとみなしてUTF-8に変換
outputFile="${file}.utf8.txt"
# 変換コマンドを実行し、標準エラー出力を変数に格納
error=$(iconv -f SHIFT_JIS -t UTF-8 "$file" > "$outputFile" 2>&1)
if [ $? -eq 0 ]; then
# 変換が成功した場合、変換後のファイルパスを出力
echo "$outputFile"
else
# 変換に失敗した場合はエラーメッセージを出力
echo "エラー: $error"
exit 1
fi
fi
ファイルを引数として渡したら、それを変換すべきか否か判断し目的の文字コードのファイル名を出力します。渡したのがファイルパスならファイルパスを出力します。これが用意できれば後は次のように find なりなんなりを通して目的のファイル群を一通り扱えます。
# findでhogeから始まるファイルを探し、convert.shに渡して変換し、utf8ディレクトリにコピー
find ./hoge* -type f -exec ./convert.sh {} \; | xargs -I{} cp {} ./utf8/