【連載】

Windows 10で始めるBash

11 BashからExcelブックにアクセスする

11/37

Bashを任意の場所で開く

BUW(Bash on Ubuntu on Windows)を使用する場合、通常はLinuxのホームディレクトリとなる「%LOCALAPPDATA%\lxss\home{ユーザー名}」フォルダーが開く。だが、任意のフォルダーで使用したいという場面は少なくない。findstrコマンドよりもgrepコマンドで文字列にマッチする行を抽出したい場合、現在のフォルダーからBashを起動できれば便利だろう。この問題はレジストリを操作すれば、簡単に解決できる。少々煩雑になるが、以下にその手順を紹介しよう。

[Win]+[R]キーを押して「ファイル名を指定して実行」を起動し、テキストボックスに「regedit」と入力して<OK>ボタンをクリックする

レジストリエディターが起動したら、HKEY_CLASSES_ROOT\Directory\Background\shellキーを開く

shellキーを右クリックし、<新規>→<キー>と順にクリックする

キー名を「新しいキー #1」から「Bash」に変更する

Bashキーの「(既定)」をダブルクリックし、データを「Open Bash」に変更したら<OK>ボタンをクリックする

続けて右ペインの何もないところを右クリックし、<新規>→<文字列>と順にクリックする

値名を「新しい値 #1」から「Extended」に変更する

Bashキーを右クリックし、<新規>→<キー>と順にクリックする

キー名を「新しいキー #1」から「command」に変更する

「(既定)」をダブルクリックで開き、データを「cmd.exe /c pushd \"%V\" && bash.exe」にしたら<OK>ボタンをクリックする

一連の操作を、HKEY_CLASSES_ROOT\Directory\shell\Bash\commandキーに対して実行する

以上で操作は終了だ。Bashを起動したいフォルダーやデスクトップの何もないところを[Shift]キーを押しながら右クリックすると、コンテキストメニューに<Open Bash>が加わったことを確認できるだろう。こちらをクリックすれば、Bashが起動する。具体的にはcmd.exe=コマンドプロンプトを起動し、pushdコマンドでカレントフォルダーを移動。その結果が正常に終了した場合に、bash.exeを起動する仕組みだ。今回は文字列値「Extended」を追加することで、[Shift]キーを押した時でないと項目が現れない設定を施しているが、常に表示させる場合は文字列値「Extended」は追加しない。

デスクトップの何もないところやフォルダーを、[Shift]キーを押しながら右クリックすると、<Open Bash>が加わる

<Open Bash>をクリックすると、カレントフォルダーに移動した状態でBashが起動する

なお、追加したレジストリエントリーを削除すれば、コンテキストメニューの項目は消えるが、面倒な場合は下記囲みの内容を、テキストエディターで下記囲みの内容を入力し、ファイル名の拡張子に「.reg」を付けてからUTF-16(BOM付き)で保存。作成したレジストリファイルをダブルクリックすれば、各エントリーを数ステップで削除できる。

Windows Registry Editor Version 5.00
[-HKEY_CLASSES_ROOT\Directory\Background\shell\Bash]
[-HKEY_CLASSES_ROOT\Directory\shell\Bash]
[-HKEY_CLASSES_ROOT\Drive\shell\Bash]
[-HKEY_CLASSES_ROOT\LibraryFolder\Background\shell\Bash]

BashからExcelブックにアクセスする

さて、今回は新しいシェルスクリプトにチャレンジしよう。日常業務でExcelを使う機会は多いと思うが、Excelブック(ワークシート)の実体はZIP形式ファイルであることをご存じだろうか。以前はバイナリ形式だったものの、Excel 2007からXMLベースに切り換え、関連ファイルをZIPでパッケージングしたファイル形式に切り替わっている。unzipコマンドをインストールし、展開するといくつかのフォルダーとファイルが展開されるはずだ。フォルダーをたどっていくと「xl\worksheets」フォルダーに「sheet1.xml」「shhet2.xml」……と、Excelブックのワークシートと同じファイル名が確認できる。だが、こちらはセルなどの設定内容であり、セルに入力した数値や文字列は含まれていない。

「unzip」は既定のパッケージに含まれいないので、「sudo apt-get install unzip」を実行してインストールする

「unzip {ファイル名}.xlsx」と実行すると、Excelブックの内容が展開される

すべてのバージョンで確認した訳ではないが、Excel 2016で作成したExcelデータの場合、数値や文字列は「xl\sharedStrings.xml」に含まれている。基本的には改行を含まないXML形式ファイルだが、セル内の文字列に「&」含まれると、エンティティ参照(XML上でダブルクォーテーションなどを扱うエスケープ文字)が加わり、「&」が置き換わる部分のみ改行が加わる仕組みだ。

sharedStrings.xmlsの内容を表示させた状態。セル内に入力した文字列が記録されている

ちなみにこちらが元となるExcelブック。特に内容は気にしないでほしい

それではここから文字列を抜き出してみよう。今回はsedではなく、改行について柔軟に対応できるperlを利用したシェルスクリプトを作成した。いつもどおりvimなどで下記の内容を作成し、chmodコマンドで実行権限を付加してほしい。

 #!/bin/bash

 BaseDir=/mnt/c/Users/kaz/Desktop
 BaseFile=$BaseDir/Book1.xlsx
 TmpDir=/tmp/_TMP
 OutputFile=$BaseDir/Output.txt

 if [ ! -d $TmpDir ]; then
    mkdir $TmpDir
 fi

 unzip -qq $BaseFile -d $TmpDir
 cat $TmpDir/xl/sharedStrings.xml | perl -pe 's/\&amp;/&/g; s/></>\n</g; s/[\n|\r]//g; s/></>\n</g; s/<[^>]*>//g' | perl -pe 's/^\n//g' > $OutputFile
 rm -rf $TmpDir

perlのオプションとしてスクリプトを実行する「e」と結果を標準出力する「p」を組み合わせ、正規表現を用いてワンライナーで行っている。ただし、改行が正しく削除されなかったので、パイプを経由して再びperlで削除した。このスクリプトを実行すると、変数「BaseFile」で指定したExcelブックから文字列だけを変数「OutputFile」で定義しているテキストファイルに出力する。

シェルスクリプトを実行するとセルの文字列をテキストファイルに出力できる

もちろんExcel本体を使えばタブやカンマで区切ったCSVファイルを出力できるため、このようなシェルスクリプトを用いる場面は少ないだろう。だが、実行するだけでファイル展開から文字列の抜き出し、後処理(展開ファイルの削除)までのワンストップで実行できる点は、シェルスクリプトならではだ。

阿久津良和(Cactus)

<お知らせ>
ITソリューション検討Information

マイナビニュースのIT Search+では、ITソリューションの検討に役立つ情報を掲載しています。
ここでは、IT Search+の人気記事ベスト3をご紹介。ぜひ、ビジネスにお役立てください。

11/37

インデックス

連載目次
第37回 HTMLコードの出力シェルスクリプトをRowspan属性に対応させる
第36回 HTMLのTableタグ出力シェルスクリプトをColspanに対応させる
第35回 BashでHTMLのTableタグを楽に
第34回 ファイル名の大/小文字一括変更シェルスクリプトをオプションで制御する
第33回 規則に応じたファイル名の大/小文字化
第32回 拡張子を一括で小文字に統一するスクリプト
第31回 Googleカレンダーから情報を抜き出す
第30回 ドライブを占有するフォルダー容量をExcelで可視化する
第29回 ドライブを占有するフォルダー容量を「R」で可視化する
第28回 ドライブを占有するフォルダー容量をSparkで可視化する
第27回 ドライブを占有する容量をフォルダーごとに簡単確認
第26回 オプションを加え汎用性を高めたレジストリーキー比較スクリプト
第25回 Reg.exeの出力結果をカラフルにして見やすくする
第24回 Reg.exeの出力結果を比較する
第23回 getoptsを活用してイベントソース可視化を大幅に拡張する
第22回 BashからPowerShellを利用する
第21回 Windowsのイベントソースを可視化してオプションで表示を分ける
第20回 Windowsのイベントログを「Cut」で切り出し可視化する
第19回 PDFファイルを画像ファイル化する
第18回 PDFファイルから一括で大量の画像を抽出
第17回 複数PDFファイルから一括テキスト抽出
第16回 文章をMarkdown記法で整える
第15回 ファイル名ではなく内容判断で重複ファイルを削除するには?
第14回 整理整頓!空のフォルダを一括でデスクトップに移送する
第13回 フォルダの中のファイルを一括でPDFにするには
第12回 フォルダーの中のエクセル請求書ファイルを合計する
第11回 BashからExcelブックにアクセスする
第10回 時間軸でデスクトップを片付ける
第9回 散らかったデスクトップを片付ける
第8回 インターネットショートカットファイルを作成する
第7回 取得結果をCSVファイルやテキストファイルに出力する
第6回 Webページの情報をシェルスクリプトで取得する
第5回 case文でスクリプト内容を整理する
第4回 実行先のフォルダーを引数で指定する
第3回 ピクセルサイズに応じて画像ファイルをリサイズする
第2回 他の画像形式をJPEG形式に変更する
第1回 フォルダー内のJPEGファイルを連番でリネームする

もっと見る



人気記事

一覧

イチオシ記事

新着記事