BUWをターミナルエミュレーター「ConEmu」と組み合わせる

今回は端末環境について少し言及したい。BUW(Bash on Ubuntu on Windows)のコンソールはcmd.exeと同じため、これまでとは意図しない動作(文字化けなど)が発生する。これはWindowsとLinuxの文字コードが異なるからだ。Windows 10自身はUnicode化されているが、Windows系アプリケーションの多くは慣例的にシフトJISを使用し、BUWはUTF-8を使用する。

BUW上のvimで日本語を含むテキストファイルを編集していると、カーソル移動時に文字が崩れることがある

BUWのプロパティダイアログ。「現在のコードページ」セクションで分かるとおりUTF-8だ。ちなみにcmd.exeからbashを呼び出した場合も同様に文字コード(コードページ)が切り替わる

ちなみにUnicodeは文字集合(表現したい文字の範囲)、UTF-8は符号化方式(文字集合を構成する文字の表現方法)の一種であり、厳密には同列に扱うべきではない。例えば「秀丸」は文字コードとして「Unicode(UTF-8)」など明確にしているが、「メモ帳」は「ANSI」「Unicode」「Unicode big endian」「UTF-8」をテキストファイルの文字コードとして指定できる。例えば「Unicode」「Unicode big endian」を選択した際の文字コードはUTF-16となり、前者はリトルエンディアン、後者は文字どおりビッグエンディアンだ。

「メモ帳」の保存ダイアログではUTF-16を「Unicode」と表記している

このようにWindowsの文字コードの扱いが不明確なのがcmd.exeにも悪影響を与えていると筆者は推察し、個人的にはcmd.exeの文字コードもUTF-8に統一してほしいぐらいだが、その話は本連載とは異なるので割愛する。さて、冒頭述べた日本語の文字化けだが、他の記事で述べたようにBUW上でSSHサーバーを起動し、Windows版SSHクライアントからアクセスすれば、大半の問題は解決するはずだ。

しかし、執筆時点ではBUWを起動してからSSHサーバーを起動するといった方法しか確認できていないため、少々面倒である。そこで試したいのがフリーのターミナル(端末)エミュレーターだ。Windows上で動作するターミナルエミュレーターはいくつかの選択肢があるものの、今回は「ConEmu」をお薦めしたい。2007年にファーストバージョンをリリースしたConEmuはタブ機能やエスケープシーケンスなどにも対応するメジャーなターミナルエミュレーターである。メッセージは英語だが、Web上には多くの日本語資料も存在するため、使用する上で困ることは少ないだろう。

ConEmuのポータブル版を初めて起動する場合、ゾーン情報によってブロックされることが多い。この情報を検出すると解除するか確認を求められるので、通常は<Unblock and Continue>をクリックする

次は基本的な動作の設定。ポータブル版の場合、実行ファイルと同じフォルダーに生成するXMLファイルへ設定情報を保存する。レジストリや他のフォルダーを選択することも可能だ

そのまま起動するとcmd.exeが起動するので、そのまま「bash」を実行する。ご覧のとおり日本語表示もひとまず問題はない

ただし、日本語を正しく表示するという点においては、フォント設定などをあらかじめ行うべきだ。ConEmuの設定項目は非常に多いため、初めて使う場合は少々うんざりするかもしれないが、フォント設定は「Main」に用意されているため、こちらで使用するフォントやフォントサイズを選択すればよい。筆者はM+とIPAを合成したMiguフォントを使用している。また、cmd.exeからbashを呼び出すと[↑]キーでコマンド履歴を呼び出すことができない。だが、ConEmuはWindowsにインストールされた各種シェルを検出し、メニューから起動する機能が備わっているため、そちらから直接bashを起動すれば正しく動作する。

[Win]+[Alt]+[P]キーを押すと起動する設定ダイアログ。「Main」セクションでフォント設定などを行う

こちらが基本的な設定を終えてvimを起動した状態。先の画面と見比べてほしい

ConEmuからbashを起動するには、<New Console dialog>ボタンの右側にある<▼>ボタンをクリックし、メニューから<{Bash}>→<{bash}>とクリックする

取得結果をファイルに出力する

それでは今回のシェルスクリプトを紹介しよう。いつもどおりvimなどで下記の内容を作成し、chmodコマンドで実行権限を付加してほしい。

 #!/bin/bash

 URLBASE=http://www.soumu.go.jp
 URL={$URLBASE}/menu_news/s-news/
 I=0
 Output="/mnt/c/Users/kaz/Desktop/foo.csv"

 if [ -f $Output ]; then
    rm $Output
    touch $Output
 fi

 Array=($(curl -s -S $URL | grep "<td" | sed -e 's/<td>//g' -e 's/<td .*">//g' -e 's/<\/td>//g' -e 's/<a.*="//g' -e 's/<\/a>//g' -e 's/">/\n/g' -e' s/ /_/g'))

 for Obj in ${Array[@]}; do
    Num=`expr $I % 4`
    case $Num in
        0 )
            StrDate=`echo ${Obj} | sed -e 's/[\r\n]\+//g'` ;;
        1 )
            StrURL=`echo ${Obj} | sed -e 's/[\r\n]\+//g'` ;;
        2 )
            StrTitle=`echo ${Obj} | sed -e 's/[\r\n]\+//g'` ;;
        3 )
            StrCat=`echo ${Obj} | sed -e 's/[\r\n]\+//g'`
            echo $StrDate,$StrCat,$StrTitle,$URLBASE$StrURL >> $Output ;;
    esac
    let I++
 done

最初はメールで取得結果を送信しようと思ったが、よくよく考えればローカルで取得した情報をインターネット経由で送信する意味がない。また、通常のLinuxと違ってBUWは常に稼働するOSではないため、今回はCSVファイルとして出力する方法を選択した。

今回新たに加えたのは6行目の変数「Output」。これまでのシェルスクリプトをご覧になった方ならご理解頂けるように、出力先となるCSVファイルをフルパスで指定している。こちらはご自身の環境に合わせて変更してほしい。また、7~11行目は出力ファイルが既に存在する場合は1度削除し、touchコマンドを使って新たに生成している。

13行目の配列「Array」に渡すsedコマンドの内容も少々変更した。今回試したところ半角変数をタイトルに持つ記事が含まれており、そのまま区切り文字としてシェルスクリプトが誤動作してしまう。そのため半角スペースを「_(アンダーバー)」に置換する処理を追加している。後は26目のファイル出力だが、「>>」とリダイレクトをシンプルに利用した。ちなみに「>」と記述した場合はファイルの既存内容を無視して上書きし、今回の場合は追記書き込みが行う「>>」を用いている。

シェルスクリプトを実行するとCSVファイルが生成されるので、Excelなどで確認すればよい

後はシェルスクリプトが生成したCSVファイルをExcelなどで開けば、1行ごとに日付やタイトル、URLなどが並ぶ仕組みだ。もし、Excelなどアプリケーションを使用したくないという場合は、変数Outputの拡張子を変更し、26行目の出力内容を「echo -e "$StrDate $StrCat\n$URLBASE$StrURL\n$StrTitle\n" >> $Output ;;」に変更。echoは「-e」オプションを追加することで「\n」を改行として扱うようになる。ただし、ダブルクォーテーションで囲まなければならないので注意してほしい。

こちらはテキストファイルとして出力した状態。テキストエディターのURLクリッカブル機能を使う場合は、こちら方が手軽かもしれない

阿久津良和(Cactus)