--eval
または-e
オプションで引数の式を評価できます。
式はシングルクォート(`
)で囲みます。
$ egison -e '(take 10 primes)'
{2 3 5 7 11 13 17 19 23 29}
--tsv
または-T
オプションにより、出力の形式がTSVになります。
評価結果のコレクションの要素のそれぞれが1行ごとに出力されます。
$ egison -T -e '(take 10 primes)'
2
3
5
7
11
13
17
19
23
29
内側の要素がコレクションである場合、それぞれの要素がタブで区切られます。
$ egison -T -e '(map p-f (between 100 110))'
2 2 5 5
101
2 3 17
103
2 2 2 13
3 5 7
2 53
107
2 2 3 3 3
109
2 5 11
内側の要素がタプルである場合にも、それぞれの要素がタブで区切られます。
$ egison -T -e '(zip nats primes)' | head -n 10
1 2
2 3
3 5
4 7
5 11
6 13
7 17
8 19
9 23
10 29
以下説明する--map
、--filter
、--substitute
オプションは入力のTSVをパースして、デフォルトでは、各行の値はタプルとして読み込みます。
--map
または-m
オプションにより入力の各行毎に処理を行うことができます。
$ seq 100 110 | egison -T -m '(lambda [$x] [x (p-f x)])'
100 2 2 5 5
101 101
102 2 3 17
103 103
104 2 2 2 13
105 3 5 7
106 2 53
107 107
108 2 2 3 3 3
109 109
110 2 5 11
--filter
または-f
オプションにより入力の各行毎にユーザ指定の条件による絞り込みを行うことができます。
デフォルトでは各行の値はタプルとして読み込まれます。
$ seq 1 20 | egison -f 'prime?'
2
3
5
7
11
13
17
19
--substitute
または-s
オプションにより入力をまるごと無限ストリームとして操作できます。
デモンストレーションとして双子素数をシェル上で出力してみます。
以下のようにシェル上で双子素数を出力できます。
$ seq 1 100 | egison -f 'prime?' | egison -T -s '(match-all-lambda (list integer) [<join _ <cons $p <cons ,(+ p 2) _>>> [p (+ p 2)]])'
3 5
5 7
11 13
17 19
29 31
41 43
59 61
71 73
以下のように1つのEgison式で双子素数を出力することも出来ます。
Egisonコマンドの出力については、パイプで渡された先で必要なだけしか評価されないようになっています。
$ egison -T -e '(match-all primes (list integer) [<join _ <cons $p <cons ,(+ p 2) _>>> [p (+ p 2)]])' | head -n 8
3 5
5 7
11 13
17 19
29 31
41 43
59 61
71 73
双子素数の場合はawk
でも短い記述で取得することができます。
$ seq 2 100 | factor | awk 'BEGIN{p=2}(NF == 2){if (p + 2 == $2){print p "\t" $2;};p=$2}'
3 5
5 7
11 13
17 19
29 31
41 43
59 61
71 73
ただし、(p,p+6)の組み合わせのようなより一般的な組み合わせの列挙に簡単に対応するのはegison
コマンドを使わないと難しいです。
--field
または-F
オプションにより、TSVのパースの方法を指定することが出来ます。
下記の用に-F 2c
と引数に与えると2列目以降をコレクションとしてまとめて扱うことが出来ます。
このオプションはsort
コマンドの-k
オプションを参考にデザインされています。
例えば、-F 2,4c
とすると2列目から4列目を{
と}
で囲みコレクションとして扱います。
$ seq 10 20 | egison -T -m '(lambda [$x] [x (p-f x)])' | egison -F 2c -m 'id'
[10 {2 5}]
[11 {11}]
[12 {2 2 3}]
[13 {13}]
[14 {2 7}]
[15 {3 5}]
[16 {2 2 2 2}]
[17 {17}]
[18 {2 3 3}]
[19 {19}]
[20 {2 2 5}]
c
以外にs
もあります。
例えば、以下のように-F 1,1s
というようにオプションを指定すると1列目の要素を"
により囲み文字列としてパースできるようになります。
また、例えば、-F 1,3s
とオプションを指定したとすると、1列目から3列目までの要素がそれぞれ"
で囲まれます。
$ seq 10 20 | egison -T -m '(lambda [$x] [x (p-f x)])' | egison -F 1,1s -F 2c -m 'id'
["10" {2 5}]
["11" {11}]
["12" {2 2 3}]
["13" {13}]
["14" {2 7}]
["15" {3 5}]
["16" {2 2 2 2}]
["17" {17}]
["18" {2 3 3}]
["19" {19}]
["20" {2 2 5}]
このチュートリアルの最後に、実データの解析をコマンドラインでEgisonで行うデモをします。 世界の各国の平均寿命の推移を解析してみます。
今回使用するこの平均寿命の元データはWorld BankのWebサイトから取得しました。 今回使用するデータは、CSVファイルになっており、ここからダウンロードできます。
CountryName,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009
Afghanistan,31.13209756,31.47529268,31.83202439,32.20426829,32.59104878,32.98987805,33.39673171,33.80914634,34.22307317,34.6375122,35.05597561,35.48141463,35.91687805,36.36131707,36.81073171,37.25712195,37.69097561,38.10629268,38.49658537,38.86185366,39.20412195,39.52695122,39.83982927,40.1492439,40.45868293,40.77058537,41.08487805,41.399,41.71092683,42.02119512,42.32936585,42.636,42.93973171,43.24209756,43.54265854,43.84090244,44.13680488,44.42980488,44.72134146,45.00985366,45.29285366,45.56726829,45.83314634,46.09243902,46.35119512,46.61641463,46.89909756,47.20531707,47.53856098,47.89885366
...
tail
コマンドにより、先頭行をスキップします。
sed
によりCSVファイルをTSVファイルを変換します。
Egisonのパターンマッチにより、対象の行のみを取得します。
$ tail -n +2 all.csv | sed -e 's/,/\t/g' | egison -T -F 1,1s -F 2c -f '(lambda [$c $ds] (match ds (list integer) {[<join _ <cons ?(gt? $ 75) _>> #t] [_ #f]}))' | sed -e 's/\t/,/g'
"Albania",62.25436585,63.27346341,64.16234146,64.88709756,65.43768293,65.82943902,66.10007317,66.31180488,66.51643902,66.73846341,66.98943902,67.2655122,67.54446341,67.8135122,68.07226829,68.32582927,68.57770732,68.83434146,69.09963415,69.37707317,69.67404878,70.00046341,70.3512439,70.71541463,71.0764878,71.39758537,71.63736585,71.77492683,71.80936585,71.75421951,71.64543902,71.5314878,71.46521951,71.487,71.61773171,71.87029268,72.24107317,72.69607317,73.19780488,73.72182927,74.23873171,74.72365854,75.16121951,75.54202439,75.85912195,76.112,76.30963415,76.47341463,76.6207561,76.76109756
...
パターン部の記述を変えるだけで、条件を色々変えた抽出が可能です。
$ tail -n +2 all.csv | sed -e 's/,/\t/g' | egison -T -F 1,1s -F 2c -f '(lambda [$c $ds] (match ds (list integer) {[<join _ <cons $x <join _ <cons ?(lt? $ (- x 5)) _>>>> #t] [_ #f]}))' | sed -e 's/\t/,/g'
"Bangladesh",47.75853659,48.23512195,48.80190244,49.41553659,49.98185366,50.22939024,49.8322439,48.66704878,46.78160976,44.36629268,41.88595122,39.93287805,38.96990244,39.25236585,40.7877561,43.33478049,46.44509756,49.53041463,52.12787805,54.04663415,55.23585366,55.80892683,56.08019512,56.30812195,56.58190244,56.95241463,57.42321951,57.93636585,58.44697561,58.95807317,59.47114634,59.98970732,60.51473171,61.04673171,61.58321951,62.12268293,62.66212195,63.19656098,63.72197561,64.23390244,64.73034146,65.20831707,65.66831707,66.10985366,66.53136585,66.93229268,67.31007317,67.66665854,68.00402439,68.32521951
...
$ grep -n -R "let " . | sed -e 's/:/\t/g' | cut -f1,2 | egison -T -F 1,1s -s '(match-all-lambda (list [string integer]) [<join _ <cons [$f $n] <cons [,f ,(+ n 1)] _>>> [f n (+ n 1)]])'
"lib/core/order.egi" 57 58
"lib/core/order.egi" 58 59
"lib/core/random.egi" 15 16