シェルスクリプト言語 kitutuki

1.文法

1.0.0 １コマンド

    コマンド名 引数1 引数2 ...

    を一つのコマンドを実行します。引数の数は任意です。
    コマンドと引数の区切りにはスペースとタブが使えます。
    実行するコマンドはディスクに保存されたプログラムが使用できます。コマンドを検索するパスには環境変数PATHが使用されます。例えばPATHに/bin:/usr/binが入っていれば（:がPATHの区切りです)

    >ls -al

    と実行すると/bin/lsと/usr/bin/lsが検索され先に検索された/bin/lsが実行されます。
    
    引数には慣習的に-で始まるオプション, --で始まるロングオプションがあります。ロングオプションは-lといった一文字のオプションが覚えにくいという理由から覚えやすい--listなどと分かりやすいオプション名で使えるようになったものです。
    引数の書き方としては、lsなど一般的な外部コマンドでは-a -lと二つオプションをつけることと-alと一つのオプションをつけることは同じ意味として処理されます。ただ残念なことにkitutukiの内部コマンドでは-alは-aと-lとは見なされません。-a -lと分けて書いてください。またオプションに引数を取るコマンドでは一般的に-T 4と書くことと-T4と書くことは同じですが、kitutukiの内部コマンドでは-T 4と書いてください。

1.0.1 標準入力、標準出力、エラー出力とリダイレクト

    一つのコマンドには入力元、出力先、エラー出力先があります。例えばvimという文章編集コマンドを実行しているときは、入力元はキーボード、出力先は画面、エラー出力先も画面です。エラー出力というのはコマンドに不具合があった場合にそれを知らせる特別なメッセージを表示する場所のことです。UNIXではこの入力元や出力先を設定によってファイルに変えることができます。それがリダイレクトです。kitutukiには以下のリダイレクトがあります。

    1>> ファイル名            標準出力をファイルに追記
    1> ファイル名             標準出力をファイルに書き込む
    2>> ファイル名            エラー出力をファイルに追記
    2> ファイル名             エラー出力をファイルに書き込む
    >> ファイル名             標準出力をファイルに追記
    > ファイル名              標準出力をファイルに書き込む
    2>&1                      エラー出力を標準出力として扱う（両方標準出力に流す)
    &>                        上と同じ
    < ファイル名              ファイルを標準入力としてコマンドに渡す

    例

    puts ファイルに書き込む文字列 > file1

    とするとfile1に「ファイルに書き込む文字列」という文字列が書き込まれます
1.0.2 １文

    コマンド1 引数... リダイレクト... | コマンド2 引数... リダイレクト...

    とコマンドを | でつなげたものが一文です。コマンド1の出力先がコマンド2の入力先として扱われて、また、そのコマンド2の出力先が次のコマンドの入力先として扱われ、、、と最後のコマンドまで実行すれば最後のコマンドが画面に出力します。
    これをパイプでつなぐといいます。

    文末には以下の区切りが使えます。

    ;               普通の文の区切り
    改行            普通の文の区切り
    &&              次の文は文のリターンコードが0(実行成功を表す)でないと実行されません
    ||              次の文は文のリターンコードが0以外(実行失敗)でないと実行されません
    &               文をバックグランド実行します

    また変数の展開は文を単位で行われます。

1.0.3 バックグラウンド処理
    文は&をつけるとバックグランド実行となります。ただし内部コマンドやユーザーコマンドの実行は並列的に行うことができません。有効なのは外部コマンドだけです。例えばdefはユーザーコマンドを定義するコマンドですが

    > def fun { sleep 10 }
    > fun &

    はバックグランド実行できません。

    > def fun { sleep 10 & }
    > fun

    は可能です。

    jobsでバックグラウンドや実行中サスペンド(CTRL-Z)したプロセスグループの一覧が見れます。

    fg jobsの一覧の番号

    でそのプロセスグループをフォアグランドに持ってくることができます。

    bg jobsの一覧の番号

    でそのプロセスグループにSIGCONTが送れます。つまり停止したプロセスを再開できます。停止する場面は例えばcpでコピー中にCTRL-Zした場合です。この場合bgするとバックグラウンドでコピーの続きをやってくれます。

1.1 クォート

    クォートとは引用を表し引用符で括るなどとして他の文として解釈されないようにするためのものです。使っている特別な記号を単なる文字列として処理したいときに使います。
    kitutukiには一文字のクォートとシングルクォートとダブルクォートがあります。一文字のクォートは\で、この後に来た記号や文字はkitutukiで特別な意味を失います。例えば行末を表す;はそのままでは行末としてkitutukiが処理しますが、\;とすると;はその意味を失い文字列として処理します。以下は実行例です。> の行が実行文。その下が実行結果です。putsは内部コマンドで引数の文字列を表示します。

    > puts 一つ目の文字列を表示; puts ２つ目の文字列を表示
    一つ目の文字列を表示
    ２つ目の文字列を表示

    > puts 一つ目の文字列を表示\; puts ２つ目の文字列を表示
    一つ目の文字列を表示; puts ２つ目の文字列を表示

    \自身を使いたい場合は\\を使います。

    > puts これが\\文字です
    これが\文字です

    シングルクォートは一つ目の'から２つ目の'までを文字列として扱います。

    > puts '一つ目の文字列; puts 二つ目の文字列'
    一つ目の文字列; puts 二つ目の文字列

    ダブルクォートも同じです。

    > puts "一つ目の文字列; puts 二つ目の文字列"
    一つ目の文字列; puts 二つ目の文字列

    シングルクォートやダブルクォートで囲まれた文字列の中でシングルクォートやダブルクォートを文字として使いたい場合はクォートしてください。

    > puts "シャア \"赤い彗星\" アズナブル"
    シャア "赤い彗星" アズナブル

    シングルクォートやダブルクォートの違いはダブルクォートは中で変数を展開する点です。変数は文字列を格納する入れ物です。

    > futatuna="赤い彗星"
    > puts "シャア \"$futatuna\" アズナブル"
    シャア "赤い彗星" アズナブル

    > futatuna="赤い彗星"
    > puts 'シャア "$futatuna" アズナブル'
    シャア "$futatuna" アズナブル

    変数以外にも$()によるコマンド置換も同じ規則です。

1.2 特殊文字列

    kitutukiではラインフィールドやキャリッジリターン, タブなどを埋め込めます。
    \n ラインフィールドとして扱う
    \r キャリッジリターンとして扱う
    \t タブとして扱う

    printは文字列を表示するコマンドです。putsと違い最後に改行しません。

    > print "初めまして\nこんにちは\n"
    初めまして
    こんにちは

    > print 初めまして\nこんにちは\n
    初めまして
    こんにちは

    > print 初めまして\\nこんにちは\\n
    初めまして\nこんにちは\n

1.3 算術演算

    足し算や掛け算など数値計算を行います。書式はbashと同じく$((計算式))です。
    使える演算子は

    (計算式)          計算順の優先順位を変える
    pai               3.14...を表す
    log 計算式
    int 計算式
    ceil 計算式
    floor 計算式
    log10 計算式
    abs 計算式
    exp 計算式
    sin 計算式
    cos 計算式
    asin 計算式
    acos 計算式
    atan 計算式
    sinh 計算式
    cosh 計算式
    sqrt 計算式

    式 ** 式 指数計算
    式 * 式  乗算
    式 / 式  除算
    式 % 式  除算の余りを得る
    式 + 式  足し算
    式 - 式  引き算

    上記は優先順位順です

    > puts $((1.1 + 1))
    2.1

    > a=1.1
    > puts $(( $a * 3 ))
    3.3

    > puts $(( log 3 + 3 ))    # log 6と同じです
    1.791759

    > puts $(( (log 3) + 3))
    4.098612

1.3.1 変数
    変数にはローカル変数、グローバル変数、環境変数があります。

    ローカル変数はスタックを使った普通の変数です。関数が呼ばれるごとにフレームが積まれ、関数から抜けるごとにフレームが除去されます。
    代入方法はa=1と=が混じったコマンド名を使い代入します。注意してほしいのはa = 1とは書けないことです。なぜならa = 1とするとaというコマンドに=,1という引数があることになるからです。
    参照方法は$aと変数名に$をつけてください。${a}でも可です。また$$aというのもあります。この違いですが${a}は単に表記上の問題のためにあります。$aと変わりがありません。$$aと$aの違いは、$aの場合kitutukiが使う特殊文字があればクォートします。$$aはクォートしません。

    >a="a;b"; puts $a
    a;b

    >a="a;b"; puts $$a
    command not found

    となります。$aの場合はputs a\;bと展開されるのに対し$$aの場合はputs a;bと展開されてbというコマンドがないというエラーがでます。

    > a=1; puts $a
    1
    > b=b; puts a${b}c      # puts a$bcとすると$bcという変数になってしまう
    abc
    > a=1; i=a; puts ${$i}    # perlのように$$iは使えません
    1
    > a=1; def fun { a=2; puts $a; }; fun; puts $a
    2
    1
    > var a=1; puts $a
    1
    > ls / | var a b c; puts $a $b $c     # パイプでデータを受け取れます
    bin boot cdrom

    グローバル変数は関数内や関数の外でも使える変数です。

    環境変数はkitutukiから起動したプロセス中でも参照できる変数です。

    変数の参照時の優先順位は

    環境変数 > グローバル変数 > ローカル変数

    となっています。

    変数とシングル、ダブルクォートの関係ですが上で書いたとおり、ダブルクォート中は変数の展開をして、シングルクォート中は変数の展開はしません。注意してほしいのはダブルクォート中の$による変数展開です。$は展開するときにクォートされるので以下のような結果になります。

    >a="a;b"; puts $a
    a;b

    >a="a;b"; puts "$a"
    a\;b

    >a="a;b"; puts "$$a"
    a;b

    あと変数には配列があります。配列はグローバル変数と同じで各関数共通に使うことができます。（ローカル変数としては扱えない）
    配列は$配列名で配列の全ての要素を空白区切りで貼り付けます。$配列名(,)で区切り文字を,に変えたりすることができます。$配列名[インデックス]で要素にアクセスできます。$配列名_sizeで配列のサイズにアクセスできます。

    > ary_new A a b c # Aという配列にa b cという要素ができる
    > puts $A[0];
    a
    > puts $A[1..2]
    b c
    > puts $A
    a b c
    > puts $A(,)
    a,b,c
    > puts $A_size
    3
    > puts $A[1..2](\n)
    b
    c

    > cat main.c | ary_new A    # 配列Aに各行が要素として格納されます
    > puts $A[0..1](\n)
    #include <stdio.h>
    #include <stdlib.h>

1.3.5 リターンコード(終了コード)

    コマンドを実行したら、そのリターンコードがローカル変数$RCODEに入っています。

    >true; puts $RCODE
    0

    >false; puts $RCODE
    1

    リターンコードにはコマンド実行中にエラーがあった場合に0以外の数値が入力されます。

1.4 コマンド置換

    コマンド結果をコマンドに貼り付けます。書式は$(複文) $$(複文)

    >$(print "puts aaa")
    command not found

    >$$(print "puts aaa")
    aaa

    上はputs\ aaaが貼り付けられるのでエラー
    下はputs aaaが貼り付けられるのでputs aaaが実行される

1.5 チルダ展開

    ~は$HOMEが貼り付けられます

1.6 グロブ

    カレントディレクトリを基点としてグロブにマッチするファイル名を貼り付けます。

    *                       任意の文字列
    ?                       任意の一文字
    []                      文字列クラス。[abc]ならaかbかcか。[a-z]ならa-z全部。[^a]はa以外。

    > puts [^mM]*
    a a.c aaa autom4te.cache bin conf10097.dir conf11225.dir conf15278.dir conf22554.sh conf9022.dir config.cache config.h config.h.in config.log config.status configure configure.in doc install.sh libkitutuki.so.1.0 kitutuki kitutuki.c kitutuki.c.bak kitutuki.c.bak2 kitutuki.h kitutuki.o kitutuki.sao kitutuki.sh test.c tmp todo.txt usage.en.txt usage.ja.txt

    カレントディレクトリからm, M以外で始まるファイル名を表示

    注意してほしいのは.*は.から始まるファイル名にマッチしますがkitutukiでは.と..にはマッチしません。

1.7 グローバルパイプ

    最後にコマンド名を書かずにパイプで終わるとグローバルパイプに書き込まれます。逆にコマンド名を書かずにパイプで始まるとグローバルパイプから読み込まれます。書き込んだ後読み込む前に別の処理を行っても大丈夫です。

    > ls | scan . | join , | 
    > lv main.c
    > sleep 10
    > | less                      # ls | scan . | join ,の結果がlessされる

1.7 ファイルハンドル
    
    <ファイル名>でファイルから一行読み込みます。続けて<ファイル名>で次の行が読めます。ファイルはオープンされているので、処理が終わるとclose ファイル名でファイルを閉じなければなりません。ファイルの終端まできたらリターンコード1を返します。STDINは特別なファイル名で現在の標準入力を表します。これは例えば関数やパイプの中などコンテキストによって適切に処理されます。

    > <main.c>
    #include <stdio.h>
    > <main.c>
    #include <stdlib.h>
    > close main.c
    main.c is closed

    >cat main.c | while <STDIN> | { | length | add \n } | less

    # グローバルパイプとの連携です。<STDIN>はcat main.cの出力を一行ずつ読み込みグローバルパイプに書き込みます。グローバルパイプから一行ごとにlength | add \nが受け取り、その行の長さと改行を付与したものを出力します。ファイルの終端まできたらリターンコードは1を返すのでwhileのループを抜け、while内で実行された全ての出力結果はlessが受け取ります。

    注意してほしいのは、この書式があるために<file1>file2というリダイレクトは< file1 > file2と空白を入れて書かないといけないということです。

1.7 ブロック

    ブロックには中括弧によるブロックとインデントによるブロックがあります。
    インデントによるブロックは:によって始まります。

    > def fun { print エフェメラ; puts クルツ }
    > def fun2:
        print アンディ
        puts クルツ

    defなどの特別な構文でなくコマンド中にでてくるブロックは文字列と同義です。
    つまり

    > ls -al | each '[ $NR -lt 10 ]' { | print } 

    とするとeachには'[ $NR -lt 10 ]'と"|print"という文字列が渡されます。この文字列をeach内でevalすることでユーザー関数を制御文のように見せることができます。この場合はls -alの出力の10行目までを表示します。

1.7 サブシェル

    ()で括ったコマンドを一つのグループとして扱います。kitutukiのサブシェルは新たにkitutukiを実行してそこでコマンドを実行させているわけではありません。新たにプロセスを作ってはいません。

    > (print aaa; print bbb) | more
    aaabbb

1.8 制御文

    if文
    if 条件文 実行文 elif 条件文 実行文 .... else 実行文

    > a=1; if [ $a = 1 ] { puts yes } else { puts no } | uc
    YES

    > a=1; vim a.sh
    if [ $a = 1 ]:
        puts yes
    else:
        puts no
    > load a.sh
    yes

    while文

    while 条件式 実行文

    > i=0; while [ $i -lt 3 ] { puts $i; i=$(($i+1)) }
    0
    1
    2

    > vim a.sh
    max=0
    cat main.c | while <STDIN>|:
        | length | var len

        if [ $max -lt $len ]:
            max=$len

    puts "main.cの最大行は$max文字です。"

    > load a.sh
    main.cの最大行は78文字です。

    while文はbreakやCTRL-Cで割り込むことで抜けられます。

    def文

    def 関数名 ブロック

    > def fun { puts $ARGV_size; puts $ARGV[0] $ARGV[1]; puts $ARGV(\n) }; fun a b c
    3
    a b
    a
    b
    c

    >vim a.sh
    def fun:
        a=2
        global b=3
        puts $a $b

    > load a.sh; a=1; global b=2; (pust $a $b; fun; puts $a $b) | less
    1 2
    2 3
    1 3

    関数内では引数はARGVという配列に渡されます。また中で宣言されたローカル変数(varによる宣言やa=1など)は関数から抜けるときに自動的に消えます。

    特殊な構文として引数名を指定することができます。

    > def fun(_ARGV) { puts $_ARGV_size; puts $_ARGV(,) }; fun a b c
    3
    a,b,c

    このとき注意してほしいのはこのように引数が指定されたユーザー関数funが呼ばれた時に関数用にスタックは作られないということです。つまりfun内では外のローカル変数にアクセスできますし、fun内で定義したローカル変数は外でも生きています。これはブロックを使ったユーザー定義の制御構文の定義に使用します。

    > vim kitutuki.sh
    def each(_ARGV):
        NR=1
        while <STDIN> |:
            eval $_ARGV[0]

            NR=$(($NR + 1))

   このように定義するとeachに渡すブロックで外で定義されたローカル変数にアクセスできます。

   > a=1; ls -al | each { | var line; puts "$a:$line"; a=$(($a + 1)) }; puts $a

1.9 ブレース展開

    a{{aa,bb}}c --> aaac abbcに展開されます

2.0 内部コマンド

    msleep

    sleepと同じく実行を止めます。画面にアニメーションが表示されます。

    true

    リターンコード 0を返します

    false

    リターンコード 1を返します

    [

    条件判定式を実行します。詳しくはman [してください。ただしbashなどの[の全ての条件式を実装しているわけではありません。
    kitutukiの[の特徴としては[ 文字列 -re 正規表現 ]で正規表現の条件式が使えるところです。マッチした場合以下の特殊なローカル変数を使います。

    PREMATCH  マッチした文字列の前の部分が入る
    MATCH マッチした文字列が入る
    POSTMATCH マッチした文字列の後の部分が入る

    >[ abcdefg -re c ]; puts $PREMATCH,$MATCH,$POSTMATCH
    ab,c,defg

    グループ化した文字列は$数値に入ります。

    >[ abcdefg -re '(.+)(c)(.+)' ]; puts $1,$2,$3
    ab,c,defg

    ほかにもkitutukiの[は文のパイプの２番目以降で実行されると標準入力から文字列を受け取って、その文字列を対象文字列の引数として判定することができます。

    >print aaa | [ = aaa ]; puts $RCODE
    0

    >print aaa | [ ! = aaa ]; puts $RCODE
    1

    この条件式は特別な構文ではなく内部コマンドなので書き方に注意してください
    [aaa=aaa]  ->[aaa=aaa]というコマンドは無いのでだめ

    [ aaa=aaa ] -> 第二引数がaaa=aaaとなるのでだめ

    [ aaa = aaa] -> 第３引数がaa]となるのでだめ
    [ aaa = aaa ] -> ok

    index 対象文字列 検索文字列
    index -i 検索したい文字列
    | index 検索したい文字列

    rindex 対象文字列 検索文字列
    rindex -i 検索したい文字列
    | rindex 検索したい文字列

    文字列から検索したい文字列が現れる場所(文字列の先頭からのインデックス)を出力します。文字列のインデックスは0からです。rindexは検索を右から左に行います

    -q 判定だけして出力をしない。リターンコードの値だけを見たいときに使います。

    -l 出力の最後に改行を加える

    -i 標準入力から文字列を受け取る(kitutukiの内部コマンドではパイプの二番目以降にコマンドが実行されると自動的に-iがついたものとして処理されます)

    -s 入力のテキストのエンコードをsjisとして処理します

    -e 入力のテキストのエンコードをeucjpとして処理します

    -w 入力のテキストのエンコードをUTF8として処理します

    -c 数値 検索回数の指定。2が指定されると２回目のマッチした位置が返されます

    -n 数値 文字列の検索開始位置を指定します。

    length 文字列
    length -i
    | length 

    文字列の長さを出力します。

    -i 入力された文字列の長さを返します。(パイプの二つ目以降にコマンドがある場合は必要ありません。)
    -l 改行を出力します。
    -s 文字列のエンコードをSJISとして数えます。
    -e 文字列のエンコードをeucjpとして数えます。
    -w 文字列のエンコードをUTF8として数えます。
    -t ターミナルでの文字列の幅を返します。

    uc
    uc -i
    | uc

    文字列を大文字に変換します

    -i 入力された文字列を処理します。(パイプの二つ目以降にコマンドがある場合は必要ありません。)
    -l 改行を出力します。

    lc
    lc -i
    | lc

    文字列を小文字に変換します

    -i 入力された文字列を処理します。(パイプの二つ目以降にコマンドがある場合は必要ありません。)
    -l 改行を出力します。

    chomp
    chomp -i
    | chomp

    文字列の最後にある改行を除去します。(LF, CRLF, CRのどれでも対応しています)

    substr 対象文字列 インデックス [カウント]
    substr -i インデックス [カウント]
    | substr インデックス [カウント]

    対象の文字列のインデックス目からカウント文字分（省略すると１文字）文字列を切り出します

    -c 入力をchompして（改行を除去して）から処理します
    -l 最後に改行文字を出力します
    -s 文字列のエンコードをSJISとして数えます。
    -e 文字列のエンコードをeucjpとして数えます。
    -w 文字列のエンコードをUTF8として数えます。

    eval コード

    コードを実行します。eval "print aaa; print bbb"などとしてください。eval print aaa; print bbbという風には実行できません

    fg ジョブ番号

    ジョブ番号のジョブをフォアグランドグループにします。（前面に持ってくる）
    bg ジョブ番号

    ジョブ番号のジョブにSIGCONTを送ります。バックグラウンドのまま実行を再開します。

    cpg ジョブ番号 プロセスグループID

    ジョブ番号のジョブのプロセスグループIDを変更します。

    jobs

    ジョブの一覧を表示します。

    rehash

    コマンドライン補完のコマンド名の一覧のキャッシュを更新します。新しいプログラムがインストールされたら実行すると、そのプログラムの補完が有効になります。

    kanjicode [-s|-e|-w]

    -s kitutukiが処理する漢字コードをSJISとして設定します
    -e kitutukiが処理する漢字コードをEUCJPとして設定します
    -w kitutukiが処理する漢字コードをUTF8として設定します
    -q 実行結果を出力しません

    kitutukiが処理する漢字コードというのは具体的には変数や配列の添え字の数え方や文字の数え方に関連する内部関数の-s,-e,-wを指定しない場合のデフォルトの文字コードということです

    linefield [-Lw|-Lm|-Lu]

    -Lw kitutukiが処理する改行コードをCRLFとして処理します
    -Lm kitutukiが処理する改行コードをCRとして処理します
    -Lu kitutukiが処理する改行コードをLFとして処理します

    kitutukiが処理する改行コードというのは内部コマンドがパイプによって文字列を一行受け取る場合の改行コードです。ほかにもjoinやsplitなど内部コマンドの処理で使われます。

    var 変数名 変数名

    ローカル変数の宣言

    var 変数名=値 変数名=値...

    ローカル変数に値を代入したり初期化します

    var -i 変数名 変数名...
    | var 変数名 変数名...

    各変数名に入力から一行ずつ受け取って、chompして一行を各変数名に代入します
    -ncオプションでchompせずに改行コードも一緒に変数に代入します

    -a パイプで受け取る文字列を一行単位ではなくて全て受け取る

    例 ls -al | var -a a

    aにls -alの出力が全て入ります

    -f 区切り文字(複数可能) 区切り文字列を改行でなく別のものに設定します。

    -nc 改行をchompせずに変数に代入する

    -i 入力から文字列を受け取り変数に設定する

    -p 出力を行う

    -l 改行を出力する

    global 変数名 変数名

    グローバル変数の宣言

    global 変数名=値 変数名=値...

    グローバル変数に値を代入したり初期化します

    global -i 変数名 変数名
    | global 変数名 変数名...

    各変数名に入力から一行ずつ受け取って、chompして一行を各変数名に代入します
    -ncオプションでchompせずに改行コードも一緒に変数に代入します

    -a パイプで受け取る文字列を一行単位ではなくて全て受け取る

    例 ls -al | global -a a

    aにls -alの出力が全て入ります

    -f 区切り文字(複数可能) 区切り文字列を改行でなく別のものに設定します。

    -nc 改行をchompせずに変数に代入する

    -i 入力から文字列を受け取り変数に設定する

    -p 出力を行う

    -l 改行を出力する

    export 変数名 変数名

    環境変数の宣言

    export 変数名=値 変数名=値...

    環境変数に値を代入したり初期化します

    export -i 変数名 変数名
    | export 変数名 変数名...

    各変数名に入力から一行ずつ受け取って、chompして一行を各変数名に代入します
    -ncオプションでchompせずに改行コードも一緒に変数に代入します

    -a パイプで受け取る文字列を一行単位ではなくて全て受け取る

    例 ls -al | export -a a

    aにls -alの出力が全て入ります

    -f 区切り文字(複数可能) 区切り文字列を改行でなく別のものに設定します。

    -nc 改行をchompせずに変数に代入する

    -i 入力から文字列を受け取り変数に設定する

    -p 出力を行う

    -l 改行を出力する

    print 出力文字列
    print -i
    | print

    -l 文字列の最後に改行文字を追加する
    -i 入力を受け取って出力する
    -e エラー出力する

    puts 出力文字列
    puts -i
    | puts

    -nl 改行しない
    -i 入力を受け取って出力する
    -e エラー出力する

    compile ファイル名

    kitutukiのスクリプトをコンパイルしてコンパイル結果をファイル名.kioとして出力する

    load ファイル名

    kitutukiのスクリプトを読み込み実行する

    -kio コンパイル済みのスクリプトファイルを読み込み実行する
    -Lw スクリプトの改行コードはCRLFとして処理する
    -Lm スクリプトの改行コードはCRとして処理する
    -Lu スクリプトの改行コードはLFとして処理する

    exit

    kitutukiを終了する

    choise メッセージ 選択肢1 選択肢2 ....
    choise -i メッセージ
    | choise メッセージ

    -l 出力を改行する
    -v リストビュー
    -n 出力をインデックスにする
    -i 入力を受け取り一行文を一選択肢とする

    | split 区切り文字の正規表現

    入力を受け取り区切り文字で区切って区切りを改行として出力する

    >print aaa bbb ccc | split
    aaa
    bbb
    ccc

    >print aaa,bbb,ccc | split ,
    aaa
    bbb
    ccc

    add 文字列

    パイプに文字列を追加する

    -n 数値 数値番目に文字列を追加する

    del
    del 文字数
    del -n インデックス 文字数

    文字数分パイプの文字列を末尾から削除する
    -n 末尾からではなくてインデックスから文字列を削除する

    join 文字列

    改行区切りの文字列に文字列を間に挟んでつなげる

    -l 出力に改行コードをつける

    >ls kitutuki* | join , | del | add \n
    kitutuki,kitutuki.c,kitutuki.c.bak,kitutuki.h,kitutuki.kio,kitutuki.ksh,kitutuki.o

    ary_new 配列名 要素1 要素2 .....
    配列を宣言

    ary_new -i
    | ary_new 配列名

    入力から各行を１要素として配列に代入(各行はchompされる)

    -a 入力を改行で区切らず全ての入力を一つの要素として代入
    -nc １行を１要素として配列に代入する場合chompしない
    -i 入力を受け取り配列の要素として代入する
    -p 出力する
    -l 出力に改行をつける

    ary_add -i 配列名
    | ary_add 配列名

    入力から各行を１要素として配列に追加する(末尾)

    | ary_add -n インデックス 配列名

    インデックスの場所に要素を追加する

    -a 入力を全て代入
    -n 数値 数値のところにインサート
    -nc chompしない
    -p 出力を行う
    -l 出力に改行をつける

    ary_erase 配列名 インデックス

    配列の要素を削除

    ary_clear 配列名

    配列名の配列を削除

    match

    正規表現

    -q
    -nl
    -n
    -a
    -i
    -f

    ary_erase 配列名 インデックス

    配列の要素を削除

    ary_clear 配列名

    配列を削除する

    match 正規表現 対象文字列
    match -i 正規表現
    | match 正規表現

    -q 出力しない
    -a 
    -nl 改行を出力しない
    -n 行番号を表示する
    -i 入力を受け取る
    -f 出力のフィールドを設定する

    >puts mikan | match -f , '(m)i(kan)'
    m,kan

    matchはegrepと違ってマッチした行ではなくてマッチした部分を出力します。
    またグループ化した場合はそのグループ化してマッチした部分をフィールド区切りで出力します。

    >puts "file:123" | match '(.+?):(\\d+)'
    file 123

    またマッチした部分は特殊なローカル変数に入ります。

    $PREMATCH マッチした前の部分
    $MATCH マッチした部分
    $POSTMATCH マッチした後の部分

    $数値 グループ化でマッチしたものが前から順番に入ります

    matchは一行ごとに処理はしません。受け取った文字列全てに検索を行います。
    一行ごとに処理したい場合はeachなどと組み合わせてください

    | sub 正規表現 変換後の文字列

    グループ化した文字列は$1,$2,...に入ります
    変換後の文字列に$自身を使いたい場合は$$を使ってください

    > print mikan | sub -l '(.)i(...)' '$1$2'
    mkan

    変換は一行に一回しか行いません。-gをつけると２回以上行ってくれます。

    -g グローバル。一行に二度以上マッチしていたら、２度以上変換を行います
    -q 出力を表示しない
    -l 改行を出力する

    マッチした回数はローカル変数SUBCOUNTに入ります。

    scan 正規表現 対象文字列
    scan -i 正規表現
    | scan 正規表現

    -i 入力を受け取る
    -f グループ化文字列のフィールドの設定

    正規表現で文字列を検索します。matchと違い一文字ずつずらして検索をかけます

    >scan . abc
    a
    b
    c

    >print abc | scan .
    a
    b
    c

    >print 'file:123' | scan '(.+?):(\\d+)'
    file 123

    >print 'file:123' | scan -f \n '(.+?):(\\d+)'
    file
    123

    read ファイル名

    -a 全て読み込む

    一行読み込む。もう一度読み込むと続きから読み込む。全てを読み込むとリターンコード1を返す。途中まで読み込んでいるときはファイルがオープンになっているのでclose ファイル名しなくてはならない

    ファイル名にはSTDINが使うとコンテキストに応じた入力から一行読み込む

    close ファイル名

    ファイルを閉じる

    -q メッセージを出力しない

    cd ディレクトリ

    ディレクトリに移動する。$PWDに現在のカレントディレクトリが入る

    cdだけだと$HOMEに移動する

    | selector

    入力から読み込んだテキストからユーザーが一行または複数行選択して選択した行を出力する

    -l 改行を出力する
    -r 前回のカーソル位置、スクロールトップ位置を使用する。
    -c カーソル位置 カーソル位置を設定する
    -t スクロールトップ位置 スクロールトップ位置を設定する
    -m 複数行の選択を許す。スペースで複数行選択できる
    -s 入力テキストをSJISとして処理する
    -e 入力テキストをEUCJPとして処理する
    -w 入力テキストをUTF8として処理する

    max 数値1 数値2

    大きいほうの数値を出力する

    -l 改行を出力する

    min 数値1 数値2

    小さいほうの数値を出力する

    -l 改行を出力する

    extname ファイル名

    拡張子を出力する

    parentname ファイル名

    ディレクトリ名のみ出力する

    noextname ファイル名

    拡張子以外のファイル名を出力する

    each ブロック
    each 条件式 ブロック 条件式 ブロック

    入力を一行ごとにブロックを実行。入力された一行はグローバルパイプと$Lに入っている。フィールドは配列$Fに入っている。行数は$NRに入っている。

    条件式は普通の文を書く。そのリターンコードが0かどうかでブロックが実行されるか決まる。

    -f フィールド 行を$Fに分けるときの区切り文字

    >print aaa\nbbb\nccc | each { | print }
    aaa
    bbb
    ccc

    >ls -al | each '[ $L -re '^m' ] { | print }
    main.c
    minato_curses.c

    > ls | each { | scan . | add -------------------\n }
    m
    a
    i
    n
    .
    c
    ----------------------
    c
    m
    d
    l
    i

    > ls | each { puts --- $F[0] --- }
    --- main.c ---
    --- cmdline.c ---

    注意)eachはパフォーマンスはwhile <STDIN> | { | command }に比べてかなり悪いです。大量のデータを扱う場合はwhile <STDIN> | { | command }を使用してください。

    foreach 文字列...文字列 ブロック

    並べられた文字列毎にブロックを実行する。文字列はグローバルパイプに入っている。

    >foreach a b c { | print }
    a
    b
    c

    for 変数 in 文字列 文字列.... ブロック

    並べられた文字列をひとつずつ変数に入れてブロックを実行する。

    >for a in a b c { puts $a }
    a
    b
    c

    select 条件式

    行ごとに条件式に当てはまる行のみ出力

    入力を一行ごとに条件式を実行。入力された一行はグローバルパイプと$Lに入っている。フィールドは配列$Fに入っている。行数は$NRに入っている。

    -f フィールドの区切り

    > print aaa bbb ccc\nddd bbb ccc\neee eee eee | select '[ $F[0] -re ^a ]'
    aaa bbb ccc

    reject 条件文

    selectの逆

    > print aaa bbb ccc\nddd bbb ccc\neee eee eee | reject '[ $F[0] -re ^a ]'
    ddd bbb ccc
    eee eee eee

    lines

    inject

    >print 1 2 5 4 3 | split | inject 0 { | var x y; max $x $y }
    5

    case 値 正規表現 ブロック 正規表現 ブロック...

    値が正規表現にマッチするなら次のブロックを実行します。

    raise メッセージ

    メッセージをエラーメッセージに入れて実行を停止する

