More Related Content
Similar to One - Common Lispでもワンライナーしたい
Similar to One - Common Lispでもワンライナーしたい (20)
One - Common Lispでもワンライナーしたい
- 5. よくやるワンライナー(1)
● アクセスログ中のhoge APIへのアクセス
● そのログ中のhoge APIのアクセス数
$ cat /var/log/nginx/access.log | grep /api/hoge
xx.xx.xx.xx - - [21/Oct/…] "GET / HTTP/1.1" ….
xx.xx.xx.xx - - [22/Oct/…] "GET / HTTP/1.1" ….
xx.xx.xx.xx - - [24/Oct/…] "GET / HTTP/1.1" ….
$ cat /var/log/nginx/access.log | grep /api/hoge |
wc -l
● 3
- 8. Common Lispでやってみる
● CSVファイル中の2列目の合計
● ぜんぶCommon Lispで。
$ cut -d ',' -f 2 data.csv | ros run -e '(print
(loop for line = (read *standard-input* nil :eof)
until (eq :eof line) sum line))' -q
6
$ ros -s split-sequence -e '(with-open-file (in
"data.csv") (print (loop for l = (read-line in
nil :eof) until (eq l :eof) sum (parse-integer (nth
1 (split-sequence:split-sequence #, l))))))' -q
● 6
- 11. ワンライナーを支援するワン!
● CSVの2列目合計をoneで。
● ぜんぶoneで。
$ cut -d ',' -f 2 data.csv | ros one '(one:for* - <
one:read* +> + 0)'
6
$ ros one '(one:for* #P"data.csv" < one:read-line*
$ #/(split-sequence #, _) $ #/(nth 1 _) $ parse-
integer +> + 0)'
6
- 17. 記号`$`: 処理の合成
● 前段の入力にパラメータ(処理)を合成
● 例
CL-USER> (one:for 入力 $ 関数or関数名 ...)
CL-USER> (one:for 1 $ print)
"1" ; 入力にprintが適用された
CL-USER> (one:for 1 $ 1+ $ print)
"2" ; 1+の後にprintが適用された
- 18. 記号`<`: 入力の上を繰り返し
● 前段の入力の上をloopする(関数で)
● 例
CL-USER> (one:for 入力 < 関数or関数名 ...)
CL-USER> (one:for '(1 2 3) < cdr $ princ)
123 ; cdrでloopしたものが出力された
CL-USER> (one:for #P"nums.csv" < one:read-line* $
print)
"id1,1"
"id2,2" ; read-line* (:EOFで終わる) でloopした
- 20. 記号`>`: 処理結果を溜め込む
● 前段の入力をリストに溜め込んで処理する
● 例
CL-USER> (one:for 入力 > 変換する関数 ...)
CL-USER> (one:for 1 > identity $ print)
(1) ; 入力がリストになる
CL-USER> (one:for '(1 2 3) < cdr > identity $
print)
(1 2 3) ; 前段の入力すべてがリストになる
CL-USER> (one:for '(1 2 3) < cdr > #/(apply #'+ _)
$ print)
6 ; 合計された
- 21. 記号`+>`: 処理結果を畳み込む
● 前段の入力をバッファせずに畳み込む
● 例
CL-USER> (one:for 入力 +> 2引数関数 [初期値] ...)
CL-USER> (one:for '(1 2 3) < cdr +> (lambda (a b)
(+ a b)) 0 $ print)
6 ; 足し込まれた
; 長い。lambdaの部分が+だけで書けるといいかも
- 23. ワンライナーを支援するワン!
● CSVの2列目合計
● 標準入力をソート
$ seq 1 5 | shuf | ros one "(one:for* - < one:read-
line* > #/(sort _ #'string<))"
1
…
5
$ ros one '(one:for* #P"data.csv" < one:read-line*
$ #/(split-sequence #, _) $ #/(nth 1 _) $ parse-
integer +> + 0)'
6
- 31. パイプを見直す
$ cat access.log | grep html | sed 日時 | sort
grep sedcat sort
grep sedcat sort( )) ) )(((
(sort (sed (grep (cat "access.log"))))
- 32. パイプを見直す
$ cat access.log | grep html | sed 日時 | sort
grep sedcat sort
grep sedcat sort( )) ) )(((
(sort (sed (grep (cat "access.log"))))
関数合成だ!
〜パイプからLispへ〜
- 33. 省メモリを考える
● 入力を全部メモリに置いてはダメ
● 入力はすぐ次の処理に流す
;; ダメなコード
;; (access.logが10GBあったら…?)
(sort (mapcar #'sed
(mapcar #'grep
(cat "access.log")))
#'string<)
(sort (loop
:for line in (cat "access.log")
:when (grep line)
:collect (sed line))
#'string<)