2013年6月9日日曜日

unix4j の備忘録

前回は、awk4j を調査したが、awk だけでは、ちと寂しいので、他の Unix コマンドを Java で使う方法も調査してみた。

その便利なライブラリは、unix4j である。
Google Code のプロジェクトで、ライセンスは、New BSD License となっている。

まずは、手っ取り早く動作確認を行う方法から。
今回は、jrunscript.exe で動作確認をするので、JDK 1.6 以上が必要。

unix4j のページには、バイナリファイルが見当たらなかったので、Maven Central Repository から jar ファイルを拝借してくる。
"unix4j"で検索すれば バージョン 0.2 が 6種類ほど引っかかる。
その内、「unix4j-command」と「unix4j-base」の jar ファイル「unix4j-command-0.2.jar」と「unix4j-base-0.2.jar」をそれぞれダウンロードする。

コマンドプロンプトを開き、jar ファイルと同じディレクトリで以下のコマンドを実行する。
%JAVA_HOME%\bin ディレクトリにパスが通っている必要がある。

dir | jrunscript -cp unix4j-base-0.2.jar;unix4j-command-0.2.jar -e "org.unix4j.Unix4j.from(java.lang.System[\"in\"]).sed(\"s/unix4j/FOOO/g\").toStdOut()"

やっていることは、標準入力からディレクトリ一覧をパイプで入力し、sed で文字列を変換し、標準出力へ結果を吐き出している。
スクリプト部分は、ファイルから読み込むこともできるので、バッチファイル化しておけば、いい感じになる。コマンドラインだとダブルクォートのエスケープとか面倒だしね。

その他にも、grep、find、tail、sort や uniq など色々使えるので、結構便利そうだ。
もちろん、通常の Java クラスとしても実装できる。


さて、ここからはおまけ。
最新の unix4j を使いたい場合に、ソースからビルドする方法を書いておく。
以下のものが必要となる。

  • JDK 1.6 以上
  • Apache Maven
  • git

今回は、以下の環境で検証した。

  • Windows 7 Professional SP1
  • Apache Maven 3.0.5
  • Java version: 1.7.0_06
  • Git for Windows 1.8.3-preview20130601

はじめに、適当なディレクトリに unix4j の git リポジトリをクローン
git clone https://code.google.com/p/unix4j/

cd unix4j

mvn clean compile jar:jar

これで、jar ファイルが出来る。
ちなみに、pom.xml には、Java 1.6 用と 1.7 用のプロファイルが定義されていて、デフォルトは、1.6 になっているが、JDK 1.7 でコンパイルした場合は、1.7 用のプロファイルが有効になるようだ。

作成された以下の jar を使う。
unix4j\unix4j-core\unix4j-base\target\unix4j-base-0.3-SNAPSHOT.jar
unix4j\unix4j-core\unix4j-command\target\unix4j-command-0.3-SNAPSHOT.jar


いやはや、今更ながら jrunscript の存在を認識できた。結構奥深いようだ。
仕事柄、ツールを利用して作業を効率化したいときが結構あるのだが、sed とか awk とか使うには、インストールできないとかで、環境面のハードルが高い。
こういうものが、地味に助かることも多い。

2013年6月8日土曜日

awk4j の備忘録

awk4j の Web ページには、以下のような説明がある。

「awk4j は、 GNU AWK 互換の言語処理環境で、 AWKスクリプトを、中間言語としてのホスト言語 ( Java, JavaFX, JavaScript, BeanShell, Groovy, Python, Scala ) に変換するトランスレータ方式で動作します。」

仕事をしていると、awk を使いたくなる場合がある。
自宅なら、MinGW とか MSYS とか、Ubuntu マシンとかあるので、困ることは無いのだが、現場によっては、ソフトのインストール自体が難しいことがある。
そんなときに、awk4j が役に立ちそうなので、ちょっと調べてみた。


  • Windows 上で動かすこととする。
  • JDK 1.6 以上がインストールされていること。

awk4j は、Java 1.6 から利用できる jrunscript コマンドを利用して実行する。

まず、awk4j のページから、awk4j-1.6.5-bin.zip をダウンロードし、適当な場所に解凍する。

最初は、実行方法を簡単に説明する。
解凍した以下のディレクトリを、コマンドプロンプトで開く
awk4j-bin\lib

以下のように実行すると、Hello World! と表示される。
AWK スクリプトを内部で Java 言語に変換しているので、CLASSPATH 環境変数の設定が必ず必要となる。
set CLASSPATH=awk4j.jar
%JAVA_HOME%\bin\jrunscript -cp awk4j.jar -l awk4j -e "BEGIN { print \"Hello World!\" }"


バッチ化する場合は、以下のようなコマンドを awk.bat として作成して、バッチと同じディレクトリに awk4j.jar ファイルを格納する。ちなみに、「%~dp0」は、バッチファイルのディレクトリを取得する記述。

@echo off
setlocal
set CLASSPATH=%~dp0awk4j.jar;%CLASSPATH%
%JAVA_HOME%\bin\jrunscript -cp %~dp0awk4j.jar -l awk4j %*
endlocal


同じように、JavaScript に変換して実行することもできる。
JavaScript の場合は、CLASSPATH 環境変数の設定は、いらないようだ。
ただし、Java と JavaScript では、実行時の挙動が異なるようだ!?
JavaScript での実行では、以下のコマンドは、同じ結果になるのだが、入力ファイルを指定しても、処理している様子がないし・・・例文で乗っている "1" とか "NF" のようなスクリプトも、JavaScript では、エラーになってしまうようだ。何か、指定方法などが間違っているのだろうか?

%JAVA_HOME%\bin\jrunscript.exe -cp awk4j.jar -l awk4j.JavaScript -e "BEGIN { print \"Hello World!\" }"


では、作成した awk.bat のコマンド例を示す。

ファイル指定で実行
awk -e "{ print $0 }" hoge.txt

パイプで実行。標準入力からデータを受け取る場合 /dev/stdin をファイル名に指定する。ここら辺の説明は、「言語仕様」リンク先でなされている。
type hoge.txt | awk -e "1" /dev/stdin