CSVエンコード問題解決

CSVエンコード問題解決

概要

Linux サーバで DB で集計して CSV ファイルをレポートする
なんてことがあるかと思います。

CSV ファイルを Linux サーバで作成し
Windows, Mac にメール添付して送信すると
どちらも CSV ファイルを開くと文字化けしてしまう問題に遭遇しました。

この問題を解決すべく調査しました。

そもそも何で文字化け?

CSV ファイルは Windows, Mac では基本 Excel が起動し開きますが
デフォルト Shift_Jis として開こうとします。

テキストファイルに一旦開いてコピーしてエクセルに貼り付ける対策を紹介しているブログもありましたが
クライアント様がお相手となる場合やファイルサイズが非常に大きい場合は
一手間かける方法は NG です。

調査 1 文字コードを変更してから mutt でメール添付送信

  1. 文字エンコードは nkf : Network Kanji Filter Version 2.0.7 (2006-06-13)
  2. メール送信は mutt 1.4.2.2i
  3. mutt の設定ファイルをいじりましたがうまくいかなかったです。

Shift_JIS

1
2
3
4
5
6
7
8
9
$ echo '大崎,yoshi,浜田,moto,松本' > sjis.csv
$ nkf -g sjis.csv
UTF-8

$ nkf -s --overwrite sjis.csv
$ nkf -g sjis.csv
Shift_JIS

$ echo "Shift_JIS だよ" | mutt -n -s "Shift_JIS CSV 添付" "kenzo.tanaka0107@gmail.com" -a sjis.csv
  • メール受信し添付ファイルをダウンロードし文字コードチェック
1
2
$ nkf -g sjis.csv
UTF-8

あれ? Shift_JIS にエンコードして送ったんだけど UTF-8 になってる

JIS (ISO-2022-JP)

1
2
3
4
5
6
$ echo '大崎,yoshi,浜田,moto,松本' > jis.csv
$ nkf -j --overwrite jis.csv
$ nkf -g jis.csv
ISO-2022-JP

$ echo "JIS だよ" | mutt -n -s "JIS CSV 添付" "kenzo.tanaka0107@gmail.com" -a jis.csv
  • メール受信し添付ファイルをダウンロードし文字コードチェック
1
2
$ nkf -g jis.csv
ISO-2022-JP

ISO-2022-JP で文字コードが変更されず送信されたけど…
やっぱり文字化け…

UTF-8

1
2
3
4
5
6
$ echo '大崎,yoshi,浜田,moto,松本' > utf8.csv
$ nkf -w --overwrite utf8.csv
$ nkf -g utf8.csv
UTF-8

$ echo "UTF-8 だよ" | mutt -n -s "UTF-8 CSV 添付" "kenzo.tanaka0107@gmail.com" -a utf8.csv
  • メール受信し添付ファイルをダウンロードし文字コードチェック
1
2
$ nkf -g utf8.csv
UTF-8

当然文字化け…

UTF-8 BOM 付き

1
2
3
4
5
6
$ echo '大崎,yoshi,浜田,moto,松本' > utf8-bom.csv
$ nkf --overwrite -oc=UTF-8-BOM utf8-bom.csv
$ nkf -g utf8-bom.csv
ISO-2022-JP

$ echo "UTF-8-BOM だよ" | mutt -n -s "UTF-8-BOM CSV 添付" "kenzo.tanaka0107@gmail.com" -a utf8-bom.csv
  • メール受信し添付ファイルをダウンロードし文字コードチェック
1
2
$ nkf -g utf8-bom.csv
ISO-2022-JP

JIS と同様の結果…

EUC

1
2
3
4
5
6
$ echo '大崎,yoshi,浜田,moto,松本' > euc.csv
$ nkf -e --overwrite euc.csv
$ nkf -g euc.csv
EUC-JP

$ echo "EUC だよ" | mutt -n -s "EUC CSV 添付" "kenzo.tanaka0107@gmail.com" -a euc.csv
  • メール受信し添付ファイルをダウンロードし文字コードチェック
1
2
$ nkf -g euc.csv
EUC-JP

ファイルエンコードではうまくいきませんでした。

調査 2 BINARY ファイルにしてみる

もっと具体的にいうと 圧縮ファイルを送ってみる

Shift_JIS で CSV が開かれるので Shift_JIS にエンコードします。

1
2
3
4
5
6
7
$ echo '大崎,yoshi,浜田,moto,松本' > sjis.csv
$ nkf -s --overwrite sjis.csv
$ zip sjis.zip sjis.csv
$ nkf -g sjis.zip
BINARY

$ echo "ZIP だよ" | mutt -n -s "ZIP 添付" "kenzo.tanaka0107@gmail.com" -a sjis.zip
  • メール受信し添付ファイルをダウンロードし文字コードチェック
1
2
3
4
5
6
$ nkf -g sjis.zip
BINARY

$ unzip sjis.zip
$ nkf -g sjis.csv
Shift_JIS

Shift_JIS のままダウンロードできてる!
これは期待できそう!

うまくいった!

総評

  • Windows, Mac で送られてきた CSV ファイルで文字化けせず開くことができました。
  • 圧縮した方が容量を下げて通信が行えるのでよくなりました。
awk で CSV の特定列を整形 〜数値を文字列扱いする〜

awk で CSV の特定列を整形 〜数値を文字列扱いする〜

概要

ある顧客データを抽出してレポートしたい、というときに
CSV ファイルで “090” などと携帯電話があると Excel で CSV ファイルを開いたときに
“90” になってしまうということがあるかと思います。

そんなときの為に特定列のみ数値を文字列扱いにしたときの内容まとめです。

Excel で数値を文字列扱いするには

1
"090"

とあったとすると

1
="090"

のように整形することで文字列扱いになります。

例)

1
"デミスハサビス",="09099999999","DeepMind"

整形してみる

  • 例)以下のような tmp.csv があるとします。
1
2
"デミスハサビス","09099999999","DeepMind"
"いとうせいこう","08088888888","エムパイヤ・スネーク・ビルディング"
  • 2 つ目のカラムのみ =を左端に追加します
    ※”(ダブルクォテーション)で囲まれた値の左側に「=」を追加します。
    ※あえて分かりやすく $1, $2, $3 の項目を明示的に指定してみました。
1
2
3
$ awk -F ',' '{print $1 ",="$2","$3}' tmp.csv
"デミスハサビス",="09099999999","DeepMind"
"いとうせいこう",="08088888888","エムパイヤ・スネーク・ビルディング"

上記のように 「=」 が追加されました。

  • 出力先を指定
1
2
3
4
$ awk -F ',' '{print $1 ",="$2","$3}' tmp.csv > output.csv
$ cat output.csv
"デミスハサビス",="09099999999","DeepMind"
"いとうせいこう",="08088888888","エムパイヤ・スネーク・ビルディング"

output.csv を Excel で開いてみます。

できました ♪

おまけ

Excel を開く際、Windows ではデフォルト SJIS なので文字コードが UTF8 の場合、文字化けします。
以下 CSV ファイルを SJIS に文字コード変換します。

1
$ nkf -sLw output.csv > output_sjis.csv

以上です。