Shift_JISのファイルを探して、UTF-8に変換するには

nkf: ファイルの文字コードを調べる

nkfコマンドを使います。

$ nkf -g ReadMe.txt 
Shift_JIS

$ nkf -g smartybook/chapter2/*.php
smartybook/chapter2/02_01.php: UTF-8
smartybook/chapter2/02_01_a.php: UTF-8
smartybook/chapter2/02_01_b.php: UTF-8
smartybook/chapter2/02_02.php: UTF-8
smartybook/chapter2/02_02_a.php: UTF-8
smartybook/chapter2/02_03.php: UTF-8
smartybook/chapter2/02_04.php: UTF-8
smartybook/chapter2/02_05.php: UTF-8
smartybook/chapter2/02_06.php: UTF-8
smartybook/chapter2/phpinfo.php: Shift_JISCode language: Bash (bash)

iconv: ファイルの文字コードを変換する

nkfコマンドでも変換できますが、ここではiconvコマンドを使います。

iconv --list で、対応している文字コードを見ると、SJISSJIS-WINがあります。SJIS-WINを明記しているので、iconvを使っています。ただし、iconv内部で、SJIS-WINSJISを区別しているのか、同じ扱いなのかは未確認です。

$ iconv --list | grep JIS
CSISO14JISC6220RO//
CSISO92JISC62991984B//
CSSHIFTJIS//
EUC-JISX0213//
JIS_C6220-1969-RO//
JIS_C6229-1984-B//
JIS_C62201969RO//
JIS_C62291984B//
SHIFT-JIS//
SHIFT_JIS//
SHIFT_JISX0213//
SJIS-OPEN//
SJIS-WIN//
SJIS//
UJIS//
Code language: Bash (bash)

SJISとSJIS-WIN、何が違うの?

SJIS-WINには、丸数字①やローマ数字Ⅱ、カッコ付きの株㈱などが追加されているのよ

むかしメーリングリストで丸数字で投稿すると、機種依存文字は使うな、と注意されたよね

ステップ1: 拡張子の一覧を表示する

まず、ディレクトリ下のファイルの拡張子の一覧を表示します。

全てのファイルを nkf -g で調べたらどうかな?

たまにJPGやGIFファイルがShift_JISと判定されてしまうことがあるのよ

nkf -g で文字コードを調べると、GIFファイルやJPGファイルの多くは BINARY と判別されますが、たまに SHIFT_JIS と判定されてしまうファイルがあります。

そこで、バイナリーファイルとわかっているファイルを除外するために、拡張子の一覧を取得します。

$ find ./smartybook/ -type f -exec basename {} \; | grep -o '\.[^.]*$' | sort | uniq  >extension.lst
$ cat extension.lst
.JPG
.as
.conf
.css
.csv
.dat
.fla
.gif
.htaccess
.html
.jpg
.js
.json
.php
.sql
.swf
.tpl
.txt
.xml
Code language: Bash (bash)

extension.lstをテキストエディターで開きます。文字コードの変換対象ではない JPG や gif などを削除して保存します。

$ cat extension.lst
.as
.conf
.css
.csv
.htaccess
.html
.js
.json
.php
.sql
.tpl
.txt
.xml
Code language: Bash (bash)

ステップ2: (文字コードの調査対象)全ファイル一覧

find_all.sh を作ります。さきほどの拡張子ごとのファイル一覧を表示するシェルスクリプトです。

#!/bin/bash -ue

for ext in $(cat extension.lst); do
  find smartybook/ -name "*$ext"
done
Code language: Bash (bash)

実行して、ファイル一覧を all.lst に保存します。

$ chmod +x find_all.sh
$ ./find_all.sh >all.lstCode language: Bash (bash)

行数を調べると、399行あります。文字コードを調査するのは399ファイル、そのうちのいくつかがShift_JISというわけです。

$ wc all.lst
  399   399 15344 all.lst
Code language: Bash (bash)

cat、head、tail、lessなどで、all.lstの内容を確認します。

$ head all.lst
smartybook/chapter5_1/DisplayTextAS3.as
smartybook/chapter5_1/XMLLoadManager.as
smartybook/chapter4_6/configs/index.conf
smartybook/chapter5_3/configs/emoji.conf
smartybook/chapter5_3/configs/style.conf
smartybook/chapter4_2_3/css/check2.css
smartybook/chapter4_2_3/css/_style.css
smartybook/chapter4_2_3/css/check.css
smartybook/chapter4_2_3/css/_common.css
smartybook/chapter4_2_3/css/_layout.css
Code language: Bash (bash)

ステップ3: Shift_JISファイルの一覧

次に、find_sjis.sh を作ります。さきほどつくったall.lstのファイル一覧から、Shift_JISファイルを探すシェルスクリプトです。

#!/bin/bash -ue

for path in $(cat all.lst); do
  encoding=$(nkf -g  $path)
  if [ "$encoding" == "Shift_JIS" ]; then
    echo $path
  fi
done
Code language: Bash (bash)

実行して、ファイル一覧を sjis.lst に保存します。

$ chmod +x find_sjis.sh
$ ./find_sjis.sh  >sjis.lstCode language: Bash (bash)

sjis.lstの行数を調べると、28行あります。Shift_JISファイルは28個あるということですね。

$ wc sjis.lst 
  28   28 1062 sjis.lst
Code language: Bash (bash)

sjis.lstの内容も表示して確認します。

$ sort sjis.lst 
smartybook/chapter2/phpinfo.php
smartybook/chapter4_2_1/admin.php
smartybook/chapter4_2_2/admin.php
smartybook/chapter4_2_3/admin.php
smartybook/chapter4_2_4/admin.php
smartybook/chapter4_3_1/admin.php
smartybook/chapter4_3_2/admin.php
smartybook/chapter4_3_3/admin.php
smartybook/chapter4_6/CMS.class.php
smartybook/chapter4_6/config.php
smartybook/chapter4_7/config.php
smartybook/chapter4_7/funcs.php
smartybook/chapter4_7/index.php
smartybook/chapter4_8/templates/menubox.tpl
smartybook/chapter4_9/fetch.php
smartybook/chapter5_1/05_01.html
smartybook/chapter5_1/admin.php
smartybook/chapter5_1/xml.php
smartybook/chapter5_3/imgsizecvt.php
smartybook/chapter5_3/ketai_ini.php
smartybook/chapter5_3/plib/emoji/Emoji.class.php
smartybook/chapter5_3/plib/image_resize.php
smartybook/chapter5_3/plib/pager_ex.php
smartybook/chapter5_3/plib/semulator.php
smartybook/chapter5_6/_read/classes/AppAmazon.class.php
smartybook/chapter5_6/_read/classes/MyList.class.php
smartybook/chapter5_6/_read/classes/MyListManager.class.php
smartybook/chapter5_6/_read/config.php
Code language: Bash (bash)

念のため、対象ファイルの内容を less で表示確認します。

$ cat sjis.lst | tee | xargs -l1 less
Code language: Bash (bash)

Shift_JISの箇所が、白で反転表示されます。q を入力すると、次のファイルを表示します。

ステップ4: UTF-8に変換する

最後のステップです。

iconv_sjis2utf8.shを作ります。sjis.lstを読み込んで、iconvでUTF-8に変換するシェルスクリプトです。

対象ファイルをShift_JISに変換して、対象ファイルに上書き保存します。

#!/bin/bash -ue

for  file in $(cat sjis.lst); do
  iconv  --from-code=SJIS-WIN  --to-code=UTF-8  $file  --output=$file
done
Code language: Bash (bash)
$ chmod +x iconv_sjis2utf8.sh
$ ./iconv_sjis2utf8.sh
Code language: Bash (bash)

対象ファイルの内容を less で表示確認します。

$ cat sjis.lst | xargs -l1 less
Code language: Bash (bash)

白反転で「<8F>o<97><CD>」と表示されていた箇所は、「出力」と変換されました。

変換前の状態を git commitしてあれば、git diff で変換の前後を確認できます。

$ git diff
diff --git a/smartybook/chapter4_2_3/admin.php b/smartybook/chapter4_2_3/admin.php
index 048f9cf..b7c5d8f 100644
--- a/smartybook/chapter4_2_3/admin.php
+++ b/smartybook/chapter4_2_3/admin.php
@@ -6,6 +6,6 @@ $smarty->assign("siteName", $siteName);
 $smarty->assign("home", $home);
 $smarty->assign("admin", $admin);
 $smarty->assign("categories", $categories);
-//<8F>o<97><CD>
+//出力^M
 $smarty->display("admin.tpl");
 ?>
Code language: Bash (bash)

ほとんどはコメント内だったよ

ここの筆者もやらかしているわね

なぜ、Shift_JISファイルが紛れ込んだんだろう?

おそらくだけど、一つめは、テキストエディターの文字コード自動判別ね。うっかりShift_JISで保存しても、テキストエディターが自動判別して表示していたから、気づきにくかったかもね。

2つめは?

ここの筆者が、収録ファイルをnkfでチェックすることを思いつかなかったのね

タイトルとURLをコピーしました