Skip to content

Instantly share code, notes, and snippets.

@greymd
Last active May 2, 2016 00:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save greymd/4d2f1ff1f25b5a050228cc1ec903420d to your computer and use it in GitHub Desktop.
Save greymd/4d2f1ff1f25b5a050228cc1ec903420d to your computer and use it in GitHub Desktop.
2016-04-30 シェル芸勉強会 LT

たのしいコマンドラインツール「egzact」の紹介。


自己紹介

ハイパーシェル芸クリエイター(※自称ではない)キュアエンジニア

きっかけ

ある方のツイート

zipで多重圧縮するのに、$ zip ファイル | zip | tee zip1 | zip | tee zip2 | zip | tee zip3 。。みたいなの出来ない? #シェル芸 #usptomo

— ぱぴろん (@papiron) 2016年3月25日
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

シェルの弱点

  • パターン生成の柔軟さ
  • 標準入力→パターン作るコマンドが全然ない。
  • 私のようなごく普通の人にはevalとブレース展開は難しい。
    • T海さんみたいな変態は稀有。

egzactとは?

  • Githubで公開中
  • インストール方法
  • 世界初?純粋関数型言語Egison製のコマンドラインツール
  • 思いついて一ヶ月くらいで作った。
  • 昨日完成。(シェル芸勉強会LT初公開)。
インストールされるコマンド
addb, addl, addr, addt, comb, conv, crops, cycle, dropl, dropr, dupl, flat, mirror, nestl, nestr, perm, stairl, stairr, subsets, takel, takelx, taker, takerx, wrap, zniq, zrep

egzactのコンセプト

このコマンドラインツールに私は3つのコンセプトを持たせました。

  • 少ない入力からのさまざまなパターン生成。
  • 既存のUNIXコマンドでよくやる操作をより簡単に、ちょっと便利にする (nixar を少し意識しています)。
  • フィールド形式のデータの操作をちょっと便利にする(Open usp Tukubaiを少し意識しています)。

少しだけ紹介

$ conv コマンド

convolution

$ seq 10 | conv 3
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
8 9 10

$ flat コマンド

$ seq 10 | flat 2
1 2
3 4
5 6
7 8
9 10

# Comma separeted file
$ cat myfile
AA,AB,AC,AD
BA,BB,BC,BD
CA,CB,CC,CD
DA,DB,DC,DD

# Field separator(fs) option is useful for keeping comma.
$ cat myfile | flat fs=, 8
AA,AB,AC,AD,BA,BB,BC,BD
CA,CB,CC,CD,DA,DB,DC,DD

$ stairl コマンド

$ echo A B C D | stairl
A
A B
A B C
A B C D

$ stairr コマンド

$ echo A B C D | stairr
D
C D
B C D
A B C D

具体例

本日のQ5

$ cat Q5 | stairl | stairr | tr ' ' '+' | sed 's/.*/print"\0 ";\0/g' | bc | grep '10$'
4+4+2 10
2+3+5 10
9+1 10

100重zip

$ echo "テストデータ" > mytext.txt
$ echo mytext.txt {1..100}.zip | conv 2 | awk '{print "zip "$2,$1}' | sh

N-gram

# uni-gramの例。一文を1文字単位で行で分割する。
$ echo "にわにはにわにわとりがいる" | grep -o .
に
わ
に
は
に
わ
に
わ
と
り
が
い
る
# 一文を2文字単位で行で分割。Bi-gram?
$ echo "にわにはにわにわとりがいる" | grep -o . | xargs -n 2
に わ
に は
に わ
に わ
と り
が い
る
# "にわにはにわにわとりがいる"のBi-gram
$ echo "にわにはにわにわとりがいる" | conv fs="" 2
にわ
わに
には
はに
にわ
わに
にわ
わと
とり
りが
がい
いる
$ cat melos.txt | conv fs="" 3

双子素数

primes () {
  yes | awk '$0=NR+1' | factor | awk '$0*=!$3'
}
# 素数が無限に出せるコマンドだああぁぁぁぁ〜^q^
$ primes 
2
3
5
7
11
13
17
19
23
29
.
.
.

双子素数。 差が2である2つの素数の組のこと。 例えば(3,5)や(5,7)。

$ primes | conv 2 | awk '$2==$1+2'
3 5
5 7
11 13
17 19
29 31
41 43
59 61
71 73
101 103
107 109
.
.
.

四つ子素数

$ primes | conv 4 | awk '$2==$1+2 && $3==$1+6 && $4==$1+8'
5 7 11 13
11 13 17 19
101 103 107 109
191 193 197 199
821 823 827 829
1481 1483 1487 1489
1871 1873 1877 1879
2081 2083 2087 2089
3251 3253 3257 3259
3461 3463 3467 3469
5651 5653 5657 5659
9431 9433 9437 9439
.
.
.

ネイピア数

$ seq 10 | flat | stairl ofs="*" | flat | wrap ofs="+" '1/(*)' | sed 's/^/1+/' | bc -l

南武線の快速から快速

$ curl -Lso- https://goo.gl/4H6Y8s | xargs > nanbu
# 最長マッチ
$ cat nanbu | grep -oE '[^ ]*,快速.*,快速'

# 最短マッチ
$ cat nanbu | grep -oP '[^ ]*,快速.*?,快速'
$ cat nanbu | stairl | stairr | grep -oE '[^ ]*,快速.*,快速' | sort | uniq

環状線になった南武線

$ cat nanbu | cycle | stairl | stairr | grep -oE '[^ ]*,快速.*,快速' | sort | uniq | nl

内回りと外回りを考慮する。

$ cat nanbu | obrev | cycle | stairl | stairr | grep -oE '[^ ]*,快速.*,快速' | sort | uniq | nl

円周率

連分数の計算(参考)で円周率を求める。

$ seq 1 2 50 | nl | awk '$1=$1"^2/"' | addr '+' |\
  mirror | flat | addr ' 1' | nestr '(*)' | \
  wrap ifs="_" '(4/ *)' | bc -l

長ったらしい松屋の定食名を簡潔にする。

$ echo "スタミナ豚バラ生姜焼定食" | mecab -E '' | awk '$0=$1' | flat | comb 2 | grep '定食$'
スタミナ 定食
豚 定食
バラ 定食
生姜 定食
焼 定食
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment