Ubuntu 17.04 で zip を展開した時の文字化けを回避する
※2017年5月24日、バージョンアップ。
Windowsで内部に日本語を含むzipファイルを作成して、それをWindows以外のOSで解凍すると文字化けする、という話はMacユーザーやLinuxユーザーの間では広く知られていると思われる面倒くさいバグなのだが、今回その文字化けを何とかしてみようと思い、Nautilus用のスクリプトを作成してみた。
何で既に回避策が存在するのにそんなもの作ろうと思ったのか、という点についても一応下の方に書いておく。
スクリプトのダウンロードとインストール
まず以下のリンクをクリックするなどしてunarなどをインストールする。
apt:unar
apt:unrar
apt:p7zip-full
#コマンドを使う場合はこうする sudo apt install -y unar unrar p7zip-full
次に端末(gnome-terminal)を起動して、以下のコマンドを実行する。
cd ~/.local/share/nautilus/scripts/ && wget https://sicklylife.jp/tool/zip_mojibake_kaihi && chmod +x zip_mojibake_kaihi && mv zip_mojibake_kaihi zipを展開する\(文字化け回避\) && cd -
するとファイル(Nautilus)の右クリックメニューにスクリプト > zipを展開する(文字化け回避)というメニューが追加されるので、zipファイルを右クリックしてそれをクリックすると、Windowsで作成したzipが文字化けすることなく展開される。
スクリプトを作った理由
Ubuntuでのzipの文字化け対策と言えば、Ubuntu Japanese Teamの日本語Remixを使うか、Ubuntu Japanese Teamのppaを使う方法が一般的だと思われるのだが、現在私が使用しているUbuntu GNOME 17.04 + Nautilus 3.24.1では以前と仕様が変わったらしく、Ubuntu Japanese Teamの文字化け回避策 (/etc/profile.d/unzip-default-charset.sh) を適用しても文字化けが直らないようになってしまっている。
Nautilus 3.24.1では↑このスクショのようにExtract Here(ここに展開する)がデフォルトになって、zip/7z/xzなどの圧縮ファイルをダブルクリックするとその場に展開されるようになり、しかも関連付けを変更しても反映されないという糞仕様になってしまっている。
file-rollerを起動してzipを開いて展開すれば(文字化け回避策を適用していれば)文字化けせずに展開されるが、いちいちfile-rollerを起動するのも面倒だし、右クリックからサクッと展開したかったのでスクリプト化してみた。来年のLTSまでに修正されるといいなぁ。
↓以下はスクリプトの中身。
#!/bin/bash # unarでアーカイブを展開 # # バージョン: 0.0.2 # ライセンス: GPLv2 # 作者 : Sickly Life # 日時 : 2017年5月24日 # 備考 : unarだと文字化けが直らない場合があったのでunzipを使うように修正。 # パスワードには未対応。 # 7zファイルは7zコマンドで展開するようにしているが、ほぼ未テスト。 # 参考 : shとbashでの変数内の文字列置換など - ろば電子が詰まっている (http://d.hatena.ne.jp/ozuma/20130928/1380380390) RMFILE=/tmp/file.YcZCaYDRKQm3us9fFyTBphd9zYeycwRKFPKGCPvMSNejW4rF2EYaHKEiTAkhDmcjTWSaXxQtBh8AFrhXPNqiVcx8vJrZFZGR2kXosxGsWqdHPfLhMmhoj2f9QVS2ByLCWkkAQgtx3pR3oQXyTkZQc79Cg2uCVcYQ6Bx4CGCiczoEQrWsQe6kDeYoHPKoRww4kMPYpAxe* TMPFILE=/tmp/file.YcZCaYDRKQm3us9fFyTBphd9zYeycwRKFPKGCPvMSNejW4rF2EYaHKEiTAkhDmcjTWSaXxQtBh8AFrhXPNqiVcx8vJrZFZGR2kXosxGsWqdHPfLhMmhoj2f9QVS2ByLCWkkAQgtx3pR3oQXyTkZQc79Cg2uCVcYQ6Bx4CGCiczoEQrWsQe6kDeYoHPKoRww4kMPYpAxe.$$ UNZIP_LOG_FILE=/tmp/file.YcZCaYDRKQm3us9fFyTBphd9zYeycwRKFPKGCPvMSNejW4rF2EYaHKEiTAkhDmcjTWSaXxQtBh8AFrhXPNqiVcx8vJrZFZGR2kXosxGsWqdHPfLhMmhoj2f9QVS2ByLCWkkAQgtx3pR3oQXyTkZQc79Cg2uCVcYQ6Bx4CGCiczoEQrWsQe6kDeYoHPKoRww4kMPYpAxe.unzip rm -f $RMFILE trap 'kill $(jobs -p); zenity --text-info --filename=$TMPFILE --title=展開終了 --width=600 --height=400; rm -f $TMPFILE; kill $$' EXIT trap 'kill $(jobs -p); zenity --text-info --filename=$TMPFILE --title=展開終了 --width=600 --height=400; rm -f $TMPFILE; kill $$' ERR if [ $# -gt 100 ]; then echo "ファイルの数が多すぎます。一度に展開できるファイル数の上限は100です。" &>> "$TMPFILE" exit 0 else declare -i num=$((100/$#)) fi declare -i count=0 for arg do name="${arg%.*}" ext="${arg##*.}" if [ "${ext,,}" = 'zip' ]; then unzip -Z -- "$arg" &>> "$UNZIP_LOG_FILE" grep 'number of entries: 1' "$UNZIP_LOG_FILE"; result=$? if [ "$result" = 0 ]; then truncate -s 0 "$UNZIP_LOG_FILE" unzip -o -O sjis -- "$arg" &>> "$TMPFILE" else sed -n '3p' "$UNZIP_LOG_FILE" | grep -E '^d'; result=$? if [ "$result" = 0 ]; then truncate -s 0 "$UNZIP_LOG_FILE" unzip -o -O sjis -- "$arg" &>> "$TMPFILE" else truncate -s 0 "$UNZIP_LOG_FILE" unzip -o -d "$name" -O sjis -- "$arg" &>> "$TMPFILE" fi fi elif [ "${ext,,}" = 'rar' ]; then unrar x -v -- "$arg" &>> "$TMPFILE" elif [ "${ext,,}" = '7z' ]; then 7z x -- "$arg" &>> "$TMPFILE" else unar -- "$arg" &>> "$TMPFILE" fi echo >> $TMPFILE # unrar & unar sed -i "/... OK.\$/d" "$TMPFILE" # unrar sed -i "/All OK\$/d" "$TMPFILE" # unzip sed -i "/^ creating: /d" "$TMPFILE" sed -i "/^ inflating: /d" "$TMPFILE" count=$(($count+$num)) echo "$count" done | \ zenity \ --progress \ --title="展開" \ --text="ファイルを展開中..." \ --percentage=0 \ --auto-close \ --auto-kill exit 0
#!/bin/bash # unarでアーカイブを展開 # # バージョン: 0.0.1 # ライセンス: GPLv2 # 作者 : Sickly Life # 日時 : 2017年5月3日 # 参考 : shとbashでの変数内の文字列置換など - ろば電子が詰まっている (http://d.hatena.ne.jp/ozuma/20130928/1380380390) RMFILE=/tmp/unar.YcZCaYDRKQm3us9fFyTBphd9zYeycwRKFPKGCPvMSNejW4rF2EYaHKEiTAkhDmcjTWSaXxQtBh8AFrhXPNqiVcx8vJrZFZGR2kXosxGsWqdHPfLhMmhoj2f9QVS2ByLCWkkAQgtx3pR3oQXyTkZQc79Cg2uCVcYQ6Bx4CGCiczoEQrWsQe6kDeYoHPKoRww4kMPYpAxe* TMPFILE=/tmp/unar.YcZCaYDRKQm3us9fFyTBphd9zYeycwRKFPKGCPvMSNejW4rF2EYaHKEiTAkhDmcjTWSaXxQtBh8AFrhXPNqiVcx8vJrZFZGR2kXosxGsWqdHPfLhMmhoj2f9QVS2ByLCWkkAQgtx3pR3oQXyTkZQc79Cg2uCVcYQ6Bx4CGCiczoEQrWsQe6kDeYoHPKoRww4kMPYpAxe.$$ rm -f $RMFILE trap 'kill $(jobs -p); zenity --text-info --filename=$TMPFILE --title=展開終了 --width=600 --height=400; rm -f $TMPFILE; kill $$' EXIT trap 'kill $(jobs -p); zenity --text-info --filename=$TMPFILE --title=展開終了 --width=600 --height=400; rm -f $TMPFILE; kill $$' ERR declare -i num=$((100/$#)) declare -i count=0 for arg do ext="${arg##*.}" if [$ext = "rar"]; then unrar xv -- "$arg" &>> $TMPFILE else unar -- "$arg" &>> $TMPFILE fi echo >> $TMPFILE sed -i "/... OK.\$/d" $TMPFILE count=$(($count+$num)) echo $count done | \ zenity \ --progress \ --title="展開" \ --text="ファイルを展開中..." \ --percentage=0 \ --auto-close \ --auto-kill exit 0