BashとかからLINQ使いたくてShelLINQってコマンド作った
BashとかからLINQ使いたくてShelLINQってコマンド作った
ウヒャァ使いやすい
LINQすき
コマンドラインでの作業をしているとき、シェルスクリプトを書いているときに突然LINQ
が使いたくなる人に向けて作ったコマンドです
docs.microsoft.com
似たような機能を持つ既存のものとしてはawk
やdatamash
があります
https://ja.wikipedia.org/wiki/AWKja.wikipedia.org
https://www.gnu.org/software/datamash/www.gnu.org
正直awk
で十分にできますがぼくはLINQ
のが使いたかったのです
ShelLINQ
インストールのしかた
git clone
してやるだけです
git clone https://github.com/xztaityozx/shellinq ./shellinq/install.sh
alias
を貼ったり補完スクリプトをbashrc
に書き込むスクリプトを同梱してるので実行すれば使えるようになります
つかいかた
GitHubのREADME.mdと同じことを書くのでそっち見てもらってもいいです
shellinq [TYPEs] [method query] ... [-o [FORMAT]]
[TYPEs]
は入力データの型です。int型の場合は[int]
と指定します。指定しない場合はint
,double
,string
のどれかからShelLINQが予想します。
ls -l
コマンドのように複数のカラムがある場合は[type1,type2,...,typeN]
というように順番に指定します。これも指定しない場合はShelLINQがすべて予想します。
[method query]
はクエリ部分です。method
にはSelect
やWhere
のようにLINQが提供するメソッド名を指定します。Qにはメソッドに与える引数部分を指定します。
例えば
Where (x => x% 2 == 0)
は
where 'x => x% 2 == 0'
と書きます。
query
ではawkのようにカラムの指定に$が使えます。
例えばwhere '$1%2==0'
と書けばShelLINQはwhere '_=>_%2==0'
と解釈します。
$0
を使うとすべてのカラムが指定できます。
[-o [FORMAT]]
は出力フォーマットをC#のコードで指定するときに使います。
具体的には処理されたデータを使ったforeach
ループのブロック部を指定します。
取り出されたアイテムは変数item
に格納されているのでそれを使用するといいでしょう。
例
Input
% seq 30|shellinq select '$1%2==0' -o 'Console.WriteLine(item?"even":"odd");'
output
odd even odd even . . .
デモ
3の倍数を抽出
seq 30 | shellinq where '$1%3==0'
3の倍数を抽出して30加算
seq 30 | shellinq where '$1%3==0' select '$1+30'
ls -lの出力を複数カラム纏めて出力
ls -l | sed '1d' | shellinq select 'new Tuple<string,int>($1,$5)'
これから
複数カラムを選択する場合が今のところかなり面倒なので何とかしたいと思っています
ls -l | sed '1d' | shellinq select '$1,$5'
ぐらいで書けると楽にできそうです
あとは入力をファイル指定出来るようにもしたいですね
雑記
ここからは雑記です
もともと雑記ですけど・・・
実装
ShelLINQは受け取ったクエリと標準入力を元に C#のソースコードを吐き出してmcsでビルド
しています
なので処理の実態部分はC#です
それゆえにawk
比べると速度はあまり出ません
ソースコードの生成には主に置換
を使っています
例えば$1
は内部クラスのメンバ変数Item1
に置換されます
クエリ内に$1
が表れるとItem1
に置換されメソッドチェーンに連結されます
なので複雑なコードには対処できないと思います・・・(スイマセン)
C#であるためデータの型
に注意する必要があります
デモ3のようにstring
とint
と書いてやらないとエラーで死にます
この辺は今後の改良で対処したいと思っています
出力について
上記まででわかる通り置換によってソースコードを作っているため期待通りの出力が得られないことがあると思います
例えばGroupBy
メソッドを使う場合です
期待しているのと違う出力のほうが出がちです
Select
などでうまく書いてやる必要がありますがここはLINQの知識が必要なので頑張らないとダメです
この辺の解決のために-o
オプションを付けていますがstring.Join
などで結合するようにすることを予定しています
まとめ
正直LINQが書けて超楽しいです
やることはawkで済む場合のことが多いですけど
良かったらみんなさんも使ってみてください
それではいいShelLINQライフを!