saphire shell

1.0.1 redirect

    > file name              write STDOUT to a file
    %2> file name            write STDERR to a file
    >> file name             append STDOUT to a file
    %2>> file name           append STDERR to a file
    < file name              using file as STDIN
    %>                       change stdout and stderr to stdout
    
1.0.2 statment

    ;               normal statment separator
    \n              normal statment separator
    &&              If a statment return code is 0, saphire evals next commandline.
    ||              If a statment return code is not 0, saphire evals next commandline.
    &               run with bachground

1.0.3 background
    You can't use saphire inner commands and user commands as background.

    > def fun { sleep 10 }
    > fun &

    the above can't run fun as background

    > def fun { sleep 10 & }
    > fun

    the above can run sleep as background

    run "jobs" to see background jobs and suspended jobs which is caught Cntrol-Z.

    fg [job number]

    above can make the job forground

    bg [job number]

    above can send SIGCONT signal to the job.

1.1 quote

    Saphire has single quote and double quote, normal quote.

    > puts first string; puts second string
    first string
    second string

    > puts first string \; puts second string
    first string ; puts second string

    If you want to send \ to programs, use \\

    > puts This is \\
    This is \\

    > puts 'first string; puts second string'
    first string; puts second string

    > puts "first string; puts second string"
    first string; puts second string

    different between single quote and double quote

    > futatuna=red
    > puts "share $futatuna aznable"
    shar red aznable

    > futatuna=red
    > puts 'share $futatuna aznable'
    share $futatuna aznable

    One quote disipates the nature in other quote

    > puts "\aaa"
    \aaa

    > puts '\aaa'
    \aaa

    > puts "'"
    '

    > puts '"'
    "

    > puts \"
    "

    > puts \'
    '

1.2 special string

    saphire can include line fields and tab.

    \n linefield
    \r carrige return
    \t tab

    > print Nice to meet you\nHello
    Nice to meet you
    Hello

    > print Nice to meet you\\nHello
    Nice to meet you\nHello\n

1.2.5 null string
    
    ''
    ""

    > puts "aaaa.c" | sub '\.' ''
    aaaac

1.3 arithmistic expression

    same bash. You can use $((expression))

    saphrie uses float number.

    the below expression saphire has

    pai               == 3.14
    log 
    int 
    ceil 
    floor 
    log10 
    abs 
    exp 
    sin 
    cos 
    asin 
    acos 
    atan 
    sinh 
    cosh 
    sqrt 

    exp ** exp --> pow
    exp * exp
    exp / exp
    exp % exp  --> mod
    exp + exp
    exp - exp

    the above is the order of priority level.

    > puts $((1.1 + 1))
    2.1

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

    > puts $(( log 3 + 3 ))    # equals log 6
    1.791759

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

1.3.1 variable
    saphire has local variables, global variables, environment variables.

    Whenver function is called, local variables stacked a stack frame.

    The substitution method of local vars is 
    a=1
    or
    var a=1

    The reference method is
    $a
    or
    ${a}
    or
    $$a

    $a is quoted with characters used by saphire.
    $$a is not quoted.

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

    ; is quoted.

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

    ; is not quoted.

    > a=1; puts $a
    1
    > b=b; puts a${b}c
    abc
    > a=1; i=a; puts ${$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

    global variables can be common used in all area.

    > global a=1; def fun { puts $a }; def fun2 { puts $a }; fun; fun2
    1
    1

    > puts aaa | global a; puts $a
    aaa

    environment variables are same bash or other shells.

    >export a=1; puts $a
    1

    > ls / | export a; puts $a
    bin

    The order of referenced variable is

    local variables > global variables = environment variables = array = hash

    If one global variables or environment variables or array or hash defined ,  same name defined variables are deleted.

    You can use alphabets and _ with variable name.

    You can use index with variable to get parts of variable.

    >a=abc; puts $a[0]
    a

    >a=abc; puts $a[0..1]
    ab

    >a=abc; puts $a[0..-2]
    ab

    >a=abc; puts $a[0,0,0,1]
    aaab

    >a=abcdefg; puts $a[0..1, 3..4, 0]
    abdea

    There are array in saphire variable. Array can't be used as local variable.
    Refferenced array puts all the elements on cmdline.

    > ary_new A
    > A[0]=a        # or ary_new A a b c
    > A[1]=b
    > A[2]=c
    > puts $A[0];
    a
    > print $A[1..2]
    b
    c
    > print $A[1,2]
    b
    c
    >print $A[0, 2, 2, 0..-1]
    a
    c
    c
    a
    b
    c

    >print $A[2..1]
    c
    b

    > print $A
    a
    b
    c
    > puts $A<,>
    a,b,c
    > puts $A_size
    3
    > puts $A[1..2]< >
    b c

    > cat main.c | ary_new A
    > puts $A[0..1]
    #include <stdio.h>
    #include <stdlib.h>

    There are hashs in saphire variable. Hashs can't be used as local variables.

    You can use utf8 character key of hash.

    >hash_new a
    >a[a]=abc
    >a[あ]=def
    >puts $a[a]
    abc

    >puts $a[あ]
    def

    >print $a
    a
    abc
    あ
    def

    >puts $a<,>
    a,abc,あ,def

    >puts $a | lines \*2+0
    abc  # getting items
    def

    >puts $a | lines \*2+1
    a     # getting keys
    あ

    There is fast refferce of variables.
    It's @.
    @ expands variables as one word, but faster than $ because @ is not expanded on the parser, but expanded on the virtual machine.

    >a=abc; puts aaa@a
    aaa
    abc

    same as

    >a=abc; puts aaa abc

    the diference

    >a=abc; puts aaa$a
    aaaabc

    If you treat big files, you should use @.

    > cat big_file.txt | each{ | split | ary_new a; puts @a[0] @a[1] }

    it's faster than

    > cat big_file.txt | each{ | split | ary_new a; puts $a[0] $a[1] }

    and the other situation is

    > cat big_file.txt | var -a a; puts $a

    is stoped because "puts $a" makes big command line, and saphire parsed it while a long time.

    > cat big_file.txt | var -a a; puts @a

    is not stopped because @a are expanded in not saphire parser, but saphire virtual machine.

    There is @@, which is a friend of @.
    If you use @@ with array, each array elements are expanded each one argument.
    > ls | ary_new a; cp @a /tmp
    happens err because all element are expanded one argument.

    > ls | ary_new a; cp @@a /tmp
    is no error because each of array elements are expanded each one arguments.

1.3.5 return code

    a command runs, then RCODE is setted. the number is the return code.

    >true; puts $RCODE
    0

    >false; puts $RCODE
    1

    ! statment

    ! reverses return code

    > ! puts aaa\nbbb | match -q a; puts $RCODE
    1

1.4 command expansion

    $(statment)
    $$(statment)

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

    >$$(print "puts aaa")
    aaa

    the above pastes "puts\ aaa" to the command line, so error eccurs
    the bellow pastes "puts aaa" to the command line, so no error

    you can use index to get parts of result

    >puts $(ls)
    AUTHOR

    >puts $(ls)[0..2]
    AUT

    There is @(statment).
    @(statment) is fastter then $(statment)

    >puts @(print a: print b)
    ab

    but, this way expands the result as one word.

    >puts @(print a)@(print b)
    a b

    saphire expands $(statment) on parser.
    saphire expands @(statment) on VM.

    > puts $(cat big_file.txt)

    is stopped because saphire expands $(statment) on parser, and very big command line is made on parser.

    > puts @(cat big_file.txt)

    is not stoppend because saphire expands @(statment) on vm.

    there is another way, it is @@(statment)

    > cp @(ls) /tmp
    is error berause saphire expands @(ls) as one word.

    > cp @@(ls) /tmp
    is no error because saphire epxands @@(ls) as each word.

1.6 glob

    same bash

    but saphire doesn't expand .* to . and ..

1.7 global pipe

    > ls | match -g . | join , |>
    > lv main.c
    > sleep 10
    > |> less                      # less get the result of "ls | match -g . | join"

    > echo aaa |>
    > |> print
    aaa
    > |> print
    aaa

    there is stackable global pipe.

    > echo aaa |-
    > echo bbb |-
    > |- print
    bbb
    > |- print
    aaa

    there is queue global pipe

    > echo aaa |~
    > echo bbb |~
    > |~ print
    aaa
    > |~ cat
    bbb

    there are number global pipes.

    > echo aaa |1
    > echo bbb |2
    > |1 print
    aaa
    > |2 print
    bb

    append str to global pipe

    > echo aaa |>
    > echo bbb |>>
    > |> print
    aaa
    bbb

    |>number == |> lines number | chomp

    > puts a\nb\nc |>
    > |>0 pomch
    a
    > |>2 pomch
    c

1.7.1 STDIN pipe

    | is same as "read -p -a". read all STDIN.

    > puts aaa\nbbb\nccc | (| print; | print; | sub -g . X)
    aaa
    bbb
    ccc
    aaa
    bbb
    ccc
    XXX
    XXX
    XXX

1.7.2 File handle
    
    <> equals read

    >puts aaa\nbbb\nccc | while(<> |>){ |> chomp | add D\n }
    aaaD
    bbbD
    cccD

    >puts aaa\nbbb\nccc | while(read |>){ |> chomp | add D\n }

1.7.3 block

    block is paresed, and a commands gets paresed block.
    If you want to run the blocks in user function, you use yeild command.

    > eval { pwd }
    /home/ab25

    > def fun { yeild 0; yeild 1; yield 1; }
    > fun { puts a } { puts b }
    a
    b
    b

    a block can get arguments.

    > def fun { yeild 0 data1 data2 }
    > fun { :a b: puts $a $b }
    data1
    data2


1.7.4 subshell

    > (print aaa; print bbb) | more
    aaabbb

    > if( ((true || flase) && true) || false ) { puts yes }
    yes

1.8 Control statment

    if statment
    if (condition) {statments} elif (condition) {statments} .... else {statments}

    > 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 | uc
    YES

    you can use linefield in blocks

    while statment

    while (condition) {statment}

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

    > vim a.sh
    max=0
    cat main.c | each {
        | length | var len

        if([ $max -lt $len ]) {
            max=$len
        }
    }

    puts max length of main.c is $max

    > load a.sh
    max length of main.c is 78

    you can press CTRL-C or break stament to interrupt while loop

    def statment

    def name block

    > 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; (puts $a $b; fun; puts $a $b) | less
    1 2
    2 3
    1 3

    ARGV is argument array.

    there is special statment

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

    the above function 'fun' doesn't make stack frame. you can access outside local variable in 'fun'.

    > vim saphire.sh
    def each(_ARGV) {
        NR=1
        while(<> |>) {
            yeild 0

            NR=$(($NR + 1))
        }
    }

    so, you can define function like the above, it's user defined loop.

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

   you can use return to exit  function.

1.9 brace expression
    
    saphire does'nt have.

2.0 process substitution

    <(statments) 

    > cat <(echo aaa) <(echo bbb)
    aaa
    bbb

    > diff <(ls ./etc) <(ls /etc)

    >(statments)

    > ls | tee >(grep main | less) | less

    the above runs ls and less, then runs ls | grep main | less

    you can write the application which manipulate terminal in >() or <()

2.0.1 exception

    try { statments } catch { exception statments }

    If occured error or a return code is not 0 in try statments, run exception statments

    > try { false; puts aaa } catch { puts bbb }
    bbb

    If the return code between pipes is not 0, do not run exception statments.

    > try { false | cat; puts aaa } catch { puts bbb }
    aaa

2.0.5 interactive shell
    
    saphire uses readline like bash. you can use the same way, but I don't understand readline perfectly, so very negligent imprementation.

    hit C-x to select file menu

    SPACE 
        select file
    TAB,W 
        insert selected file name to cmdline
    BackSpace
        move to parent directory
    Return
        move to directory under cursor

    
2.0.6 option
    -c "command" run command
    -rs run the run time script as source file
    -ro run the run time script as compiled file
    -rn no run the run time script
    -ts terminal kanji code is sjis
    -tw terminal kanji code is utf8
    -te terminal kanji code is eucjp
    -s saphire kanji code is sjis
    -w saphire kanji code is utf8
    -e saphire kanji code is eucjp
    -Lu saphire line field is LF
    -Lm saphire line field is CR
    -Lw saphire line field is CRLF
    --version show version

    you can use saphire on bash shell

    for example

    $ ls | saphire -c '| each { | scan . | each { | add -n 0 X } | join "" | pomch }' | less

    
2.0.7 excution of script file

    saphire FILE
    saphiresh FILE
    
    saphire is fastter than saphiresh
    
    saphire sets FILE to global variable "$SCRIPT_FILE_NAME"
    saphire sets parametors to $ARGV array.
    
    you must write script file with utf8
    you must write script file with LF line field
    
2.1 inner commands

    msleep
    
    same as sleep

    true

    set return code as 0

    false

    set return code as 1

    [

    -I read STDIN

    Condition judgment.
    saphire can use -re to regex condition.
    If matching, you use below local variables.

    $PREMATCH  the parts of before matching.
    $MATCH the patrts of matching
    $POSTMATCH the parts of after matching.

    $number the parts of group maching.

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

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

    bellow is friends of -re

    -rei ignore case
    -rem multiline
    -reim, -remi iignore case and multiline

    saphire can use compare with strings

    -slt
    -sle
    -sgt
    -sge
    -silt ignore case
    -sile
    -sigt
    -sige

    saphire can use compare with string from STDIN

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

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

    >print aaa | if([ -I = aaa ]) { puts yes } else { no }
    yes

    >print aaa | if(| [ = aaa ]) { puts yes } else { no }
    yes

    this is not special grammer, but a inner commands.

    [aaa=aaa]  ->[aaa=aaa] is not command
    [ aaa=aaa ] -> second argument is aaa=aaa, so error

    [ aaa = aaa] -> the third argument is aa], so error
    [ aaa = aaa ] -> ok

    index [target] [string]
    index -I [string]
    | index [string]

    rindex [target] [string]
    rindex -I [string]
    | rindex [string]

    output index number which is searched.

    rindex searchs from tail to head.

    -q quiet
    -nl no add line field to output

    -I get string from STDIN
    -c number searching count
    -n number set start point
    -b count with byte unit
    -t count with terminal width unit
    -i ignore case

    length string
    length -I
    | length 

    get length of string

    -I use STDIN
    -nl no add lienfield to output
    -s assume encode as SJIS
    -e assume encode as eucjp
    -w assume encode as UTF8
    -t ouput terminal width
    -b byte unit
    -L count linefield number

    uc
    uc -I
    | uc

    change case to upper

    -I use STDIN
    -l add linefield to output
    -s assume input as sjis ecode
    -e assume input as eucjp
    -w assume input as utf8

    lc
    lc -I
    | lc

    change case to lower

    -I use STDIN
    -l add linefield to output
    -s assume input as sjis ecode
    -e assume input as eucjp
    -w assume input as utf8

    chomp
    chomp -I
    | chomp

    delete linefield of tail. (ok for LF or CRLF or CR)

    pomch
    | pomch

    add linefield to tail using linefield setting.
    if linefield setting is LF, add LF, if linefield setting is CRLF , add CRLF, and so on.

    -Lw add CRLF to the tail
    -Lm add CR to the tail
    -Lu add LF to the tail

    substr target index [count]
    substr -I index [count]
    | substr index [count]

    -c chomp string before processes
    -l add linefield to tail
    -s assume encode as SJIS
    -e assume encode as eucjp
    -w assume encode as UTF8
    -b byte unit

    eval block
    | eval

    run block
    "| eval" reads from STDIN, and eval it.

    fg job number

    forground job

    bg job number

    send SIGCONT to job

    jobs

    show list job 

    rehash

    refresh completion list. use after installing programs.

    kanjicode [-s|-e|-w]

    -s assume kanji code as SJIS
    -e assume kanji code as EUCJP
    -w assume kanji code as UTF8
    -q quiet

    saphire uses this setting to count index of variable, inner commands with manipulating string.

    linefield [-Lw|-Lm|-Lu]

    -Lw assume linefields as CRLF
    -Lm assume linefields as CR
    -Lu assume linefileds as LF
    -q quiet

    saphire uses this setting to inner commands, which is join or read, and so on.

    var name name name...

    define local variable

    var name=value name=value...

    define local variable

    var -I name name ...
    | var name name ...

    definitio of localvariable, which is initialized from STDIN.

    > print aaa\nbbb | var a b; puts $a,$b
    aaa,bbb

    -nc no chomp
    -a use not one line of STDIN, but all STDIN

    for example
    >print aaa\nbbb | var -a a
    >print $a
    aaa
    bbb

    -f "field characters" set fields
    -nc no chomp
    -I read from STDIN
    -p enable output
    -l add linefield to tail

    global name name

    definition of global variables

    global name=value..

    global -I name name
    | global name name...

    definition of global variable with initializing from STDIN

    -nc no chomp
    -a initialize not one line of STDIN but all STDIN

    -f "fields" set fields
    -nc no chomp
    -I read from STDIN
    -p enable output
    -l add line fields to tail

    export name name
    export name=value name=value...
    export -I name name name
    | export name name ...

    definition of environment variable

    -nc no chomp
    -a read all STDIN, not one line
    -f "fields" change fields
    -nc no chomp
    -I read from STDIN
    -p enable output
    -l add linefiled to tail of output

    print STRING
    print -I
    | print

    -l add linefield to tail
    -I read from STDIN
    -f set field

    puts STRING
    puts -I
    | puts

    -I read from STDIN
    -f set field

    compile source file

    compile source file and write objectfile.

    load [source file or object file]

    run script file

    -sao use object file

    exit

    exit saphire

    -f though there are jobs, force to exit saphire

    split -I [regex]
    split string [regex]
    | split [regex]

    split strings
    if there is not regex, bring \s+ to the command

    -f [string] change field
    -I read from STDIN
    -m multiline
    -i ignore case
    -s assume encode as SJIS
    -e assume encode as eucjp
    -w assume encode as UTF8

    >split "aaa bbb ccc"
    aaa
    bbb
    ccc

    >split "aaa,bbb,ccc" ,
    aaa
    bbb
    ccc

    >print aaa bbb ccc | split
    aaa
    bbb
    ccc

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

    >ls | chomp | split -m -f "," | pomch
    main.c,test.c,Makefile,configure.in

    add [string] [string] ..
    add { block } {block} { block}

    add string to pipe

    -n [index] add string to point of the index
    -L [line number] add string to the head of the line
    -s assume encode as SJIS
    -e assume encode as eucjp
    -w assume encodde as UTF8
    -b count byte unit index of -n

    > print aaa | add ccc\n
    aaaccc

    > print abc | add -n -2 { print d }
    abcd

    > print aaa | add -n 1ccc\n
    acccaa

    > puts andy\nefemera\ntatta | add -L 1 @(puts ard)
    andy
    ard
    efemeta
    tatta

    > puts andy\nefemera\ntatta | add -L 1 {puts ard}
    andy
    ard
    efemeta
    tatta

    del
    del [number]
    del -n [index] [number]

    delete string of pipe

    -n delete from the point of index
    -s assume encode as SJIS
    -e assume encode as eucjp
    -w assume encode as UTF8
    -b count as byte unit of index with -n
    -L [line number] delete the line

    >print abcdE | del 
    abcd

    >print abcd | del -n 1
    acd

    >print aaa\nbbb\nccc\nddd\neee | del -L 2 2
    aaa
    bbb
    eee

    join -I [field]
    join string [field]
    | join [field]

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

    x string count
    | x count

    output string as many as count pieces

    > print a | x 5 | pomch
    aaaaa

    select [ block ]

    select lines. If return code of block is true, output the line.

    >print aaa\nbbb\nccc | select { | [ -re ^a ] }
    aaa

    | lines [line number] [ [-b|-B] block]...

    -r reverse

    you can use line number as

    number 
    or
    number..number 

    \*number1+number2 y = number1*x + number2 [x=1,2,3...]

    (lines \*2+1 --> odd number line)
    (lines \*2+0 --> even number line)

    x[number1]+number2 = you can get number1 count lines with block

    add -b block to run block once with the lines as STDIN
    add -B block to run block with every lines as STDIN

    >print aaa\nbbb\nccc | lines 0 0..1
    aaa
    aaa
    bbb

    >puts aaa\nbbb\nccc | lines -r
    ccc
    bbb
    aaa

    >print aaa\nbbb\nccc | lines 0 1..0
    aaa
    bbb
    aaa

    >print aaa\nbbb\nccc\nddd | lines 0 -B { | uc } 1 -B { | sub -g . D } 2..-1
    AAA
    DDD
    ccc
    ddd

    >ls | lines 0 -B { | var a } 1..-1 -b { | var -a b }

    a is first line.
    b is last line.

    >ls | lines 0 -B { | var a } 1..-1 -B { | var -a b }

    a is first line.
    b is since the second line

    > times 15 { :i: ++ i; puts i } | lines x5+0 -B { | join , }
    1,2,3,4,5
    6,7,8,9,10
    11,12,13,14,15

    | rows [number] [ [-b|-B]block]

    -s assume encode as SJIS
    -e assume encode as eucjp
    -w assume encode as UTF8
    -r reverse

    number
    number..number2

    \*number1+number2 y = number1*x + number2 [x=1,2,3...]

    (rows \*2+1 --> odd number character)
    (rows \*2+0 --> even number character)

    x[number1]+number2 = you can get number1 count character with block

    add -b block to run block once with the lines as STDIN
    add -B block to run block with every lines as STDIN

    > print abcdefg | rows 0 3 -b { | puts }
    ad

    > print abcdefg | rows 0 -b { | uc } 1..-1 -b { | puts }
    Abcdefg

    > print abcdefg | rows 0 -b { | uc } 1..-1 -B { | puts }
    Ab
    c
    d
    e
    f
    g

    > print abcdefg | rows -r |pomch
    gfedcba

    ary_new name element1 element2 ...

    ary_new -I
    | ary_new name

    -a read all STDIN
    -nc no chomp
    -I read from STDIN
    -p enable output
    -l add linefield to tail

    ary_add -I name
    | ary_add name

    | ary_add -n index name

    -a read all STDIN
    -n number insert at index of number
    -nc no chomp
    -p enable output
    -l add linefield to tail

    ary_erase name index

    erase element of array

    match

    regex comparing operator

    match -I [regex] -> read from STDIN
    commands | match [regex] -> read from output of command
    match [string] [regex]
    command | match -L [regex] -> like grep
    command | match -g [正規表現] -> comapre all output

    -q quiet
    -nl no add linefield ot tail
    -n add list number to output
    -I read from STDIN
    -f [string] use string to field of grouping match. default is tab.
    -g global. 
    -L same as grep
    -i ignore case
    -m multiline
    -s assume encode as SJIS
    -e assume encode as eucjp
    -w assume encode as UTF8

    local variables

    $PREMATCH the parts of before matching point
    $MATCH the parts of maching point
    $POSTMATCH the parts of after matching point

    $MATCH_COUNT matching count

    $number group maching

    >ls | match -L -n minato_curses
    11:minato_curses.c
    12:minato_curses.o
    13:minato_curses.h

    (line oriented)

    >ls | match .
    A

    (one time)

    >ls | match -g .
    A
    U
    T
    H
    O
    R
    S

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

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

    >print abcdef | match '..(.).(.).'; puts $1,$2
    c	e
    c,e

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

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


    > ls | each{ | match -q -i m && | print }
    Makefile
    Makefile.in
    README.ja.txt
    autom4te.cache
    gmon.out.hayai
    gmon.out.osoi
    saphire_commands.c
    saphire_commands.o
    saphire_main.c
    saphire_main.o
    saphire_vm.c
    saphire_vm.o
    main.c

    scan [string] [regex]
    | scan [regex]

    same as match -g

    >ls | scan .
    A
    U
    T
    H
    O
    R
    S

    scan regex { block }

    when matching, run block.
    STDIN has matched string. You shouldn't use . regex for matching each character because of performance.

    > print aaaa123-bbb1234 | scan '\d+' { | x 2 | pomch }
    123123
    12341234

    > cat big_file.txt | scan . { | print }

    saphire will run while some days.

    You can use below local variables.

    $PREMATCH --> From head of string to matching point
    $PREMATCH2 --> From the point of matching before to matching point this time
    $MATCH --> matching string
    $POSTMATCH --> after matching string
    $1 〜 $9 --> group strings

    Pay attention that scan without -m reads one line from STDIN.

    > print 123b456\n789b000 | scan b { }

    In the block
    first time
    PREMATCH 123
    PREMATCH2
    MATCH b
    POSTMATCH 456

    secound time
    PREMATCH 789
    PREMATCH2
    MATCH b
    POSTMATCH 000

    erase string regex
    | erase regex

    erase parts of maching regex from the string.

    -g global
    -m multiline
    -i ignore case
    -s assume encode as SJIS
    -e assume encode as eucjp
    -w assume encode as UTF8

    > erase abcdefg\n .
    bcdefg

    > erase abcdefg\n '.$'
    abcdef

    > puts abcdefg | erase '(.).(.)$'
    abcdf

    sub [string] [regex] [string2]
    | sub [regex] [string]

    Conversion of string

    >ls
    saphire_vm.c
    saphire_vm.o
    libsaphire.so
    libsaphire.so.1
    libsaphire.so.1.0
    main.c
    readline.c
    readline.o

    >ls | sub a A
    sAphire_vm.c
    saphire_vm.o
    libsaphire.so
    libsaphire.so.1
    libsaphire.so.1.0
    main.c
    readline.c
    readline.o

    >ls | each{ | sub a A }
    sAphire_vm.c
    sAphire_vm.o
    libsAphire.so
    libsAphire.so.1
    libsAphire.so.1.0
    mAin.c
    reAdline.c
    reAdline.o

    > sub -g aaa a x | pomch
    xxx

    > print mikan | sub '(.)i(...)' '\1\2'
    mkan

    -g global
    -q quiet
    -i ignore case
    -m multiline
    -c check before conversion
    -s assume encode as SJIS
    -e assume encode as eucjp
    -w assume encode as UTF8

    local variable $SUB_COUNT is matching count

    sub regex { block }

    If matching regex, run block which has match string as STDIN. Output of the block is using change the strings.

    > print abcd | sub -g . { print x } | pomch
    xxxx

    In the block, blew local variables can be used

    $PREMATCH --> From head of string to matching point
    $PREMATCH2 --> From the point of matching before to matching point this time
    $MATCH --> matching string
    $POSTMATCH --> after matching string
    $1 〜 $9 --> group strings

    Pay attention that sub without -m reads one line from STDIN.

    > print 123b456\n789b000 | sub -g b { }

    In the block
    first time
    PREMATCH 123
    PREMATCH2
    MATCH b
    POSTMATCH 456

    secound time
    PREMATCH 789
    PREMATCH2
    MATCH b
    POSTMATCH 000

    read

    -a all
    -n number number of reading line
    -p preserve

    read from STDIN

    > puts aaa\nbbbb | read
    aaa

    > puts aaa\nbbb | (read | chomp | add D\n; read | chomp | add E\n)
    aaaD
    bbbE

    > puts aaa\nbbb | read -a
    aaa
    bbb

    > puts aaa\nbbb\nccc\neee\nfff | (read; read -n 2 | cat -n; read -a)
    aaa
          1 bbb
          2 ccc
    eee
    fff

    > puts aaa\nbbb\nccc | (read -p -a; read -a)
    aaa
    bbb
    ccc
    aaa
    bbb
    ccc

    read [file name]

    read from the file with one line
    if read EOF, retern 1 and close the file

    -n [number] read as many as number line
    -a read all

    cd directory

    move directory

    | selector

    read from STDIN and output one or multi line which is selected by user

    -r use last time cursor point and scroll top
    -c [point] set cusor point
    -t [point] set scrolltop point
    -m multiline. user can use space to multi select
    -s assume encode as SJIS
    -e assume encode as EUCJP
    -w assume encode as UTF8

    max number1 number2

    > max 2 3
    3

    -nl no add linefield to ouput

    min number1 number2

    >min 2 3
    2

    -nl no add linefield to output

    extname [file name]

    -I read data from STDIN
    -nl no output linefield

    > print aaa.c | extname
    c

    parentname [file name]

    -I read data from STDIN
    -nl no output linefield

    > print /abc/def/ghi | parentname
    /abc/def/

    noextname [file name]

    -I read data from STDIN
    -nl no output linefield

    > print aaa.c | noextname
    aaa

    raise message

    send error happends

    hash_new name name2 ...
    | hash_new name

    make hash

    > print key value key2 value2 key3 value3 | split | hash_new a
    > puts $a[key]
    value

    | hash_add HASH_NAME

    > print key value | split | hash_add a

    add data to hash

    hash_erase name key

    erase hash element

    sweep

    erase all global variable, hashs, arrays

    -f erase function too
    -reg erase regex cashe
    -f erase function defines
    -g erase global pipes

    if argument exists, erase a variable of that name.

    sweep A B C   # erase A, B, and C variable

    show

    show all globaal variables, hashs, arrays

    -v show value of global variables

    printf format param1 param2...
    | printf format

    -l add linefield to tail

    you can use format like C language.

    > printf "%010.3f" 111.1
    0000000111.100

    > ls | printf "[%s], [%s], [%s]\n[%s], [%s], [%s]\n"
    [AUTHORS], [saphire_commands.c], [saphire_curses.c]
    [saphire_debug.c], [saphire_extra.c], [saphire_hash.c]

    | sort
    | sort [block]

    sort

    if there is no block, send { [ $a -slt $b ] } to sort

    $a is left one line
    $b is right one line

    > ls | sort
    > ls | sort { [ $a -slt $b ] }


    > ls | sort { [ $a -sgt %b ] }

    > print $ARGV | sort { [ $a -slt $b ] } | ary_new ARGV2

    ++ [local variable name]

    add 1 to local variable

    | ++

    add 1 to pipe

    -- [local varialbe name]
    reduce 1 to local variable

    | --
    reduce 1 to pipe

    | + number
    add number to pipe

    | - number
    redurce pipe number

    | \* number
    multiplication

    | / number
    dividing calculation

    | mod number
    mod

    | pow number
    pow

    range number1 number2

    > range 1 5
    1
    2
    3
    4
    5

    > ls | ary_new a; puts $a[$(range 30 50 | chomp | join ,)]

    pcat block block2...

    > pcat { echo aaa } { puts bbb } | less
    aaa
    bbb

    | ptee block block2...

    >puts aaa | ptee { | cat } { | print } { | sub -g a b }
    aaa
    aaa
    bbb

    you can nest with ptee

    > puts aaa | ptee { | cat } { | ptee { | print } { | print } } | less
    aaa
    aaa
    aaa

    return number

    exit from function

    yield [number]

    run parnt block argument. if no argument, saphire run "yeild 0"

    > def fun { yeild 0; yeild 1; yield 1; }
    > fun { puts a } { puts b }
    a
    b
    b

    each { block }

    evaluate block at every lines. STDIN pipe has a line string.

    >ls | each { | print }
    main.c
    sub.c

    If the block has arguments, you can get line number of data.

    > ls | each { :i: | print | add -n 0 $i }
    0:main.c
    1:sub.c

    foreach string...string block

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

    >ary_new A a b c
    >foreach $A< > { | pomch }
    a
    b
    c

    >ary_new A a b c
    >foreach @@A { | pomch }
    a
    b
    c

    | p

    Filer which is nothing to do. This is for user debug with looking at data between commands.

    in p, hit SPACE or RETURN to send data to next command.
    in p, hit q or Escape key, Control-c to stop running statment.

    -c cursor position  setting cursor position
    -t scrolltop position   setting scrolltop position
    -s assume data as SJIS encoding
    -e assume data as eucjp encoding
    -w assume data as UTF8 encoding(default)

the user function defined in saphire.sa

    times count block

    run block count times

    If the block has arguments, you can get count number

    > times 3 { :i: puts $i }
    0
    1
    2

    upto [init num] [final num ] [block]

    > upto 1 5 { :i: puts $i }
    1
    2
    3
    4
    5

    downto [init num] [final num] [block]

    >downto 5 3 { :i: puts $i }
    5
    4
    3

    step [init num] [final num] [aditional num] [ block ]

    >step 3 10 3 { :i: puts $i }
    3
    6
    9

    | field [number]

    return Nth field

    | field_num

    return field number

    shelp

    view USAGE.txt

    smake

    run make and get result with selector. user can select the result of make to run editor the line.

    sgrep

    run grep and get result with selector. user can select the result of grep to run editor the line

    for name in string string.... block

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

    >ary_new A a b c
    >for a in $A< > { puts @a }
    a
    b
    c

    >ary_new A a b c
    >for a in @@A { puts @a }
    a
    b
    c

    case value regex1 block1 regex2 block2...

    >a=1; case $a 0 { puts a } 1 { puts b } 2 { puts c } 3 { puts d }
    b

sample

    Upper case head of file name

    >ls | each { | var a; uc $a[0]; puts @a[1..-1] }
    >ls | each { | rows 0 { | uc  } 1..-1 { | pomch } | chomp }

    ls | grep minato | grep -v \~ | wc -l

    > nr=1; count=0; ls | each { | match -q minato && | ! match -q \~ && (++ count; print $nr\:; | print ); ++ nr }; puts $count

    egrep

    > ls | each{ | [ -re 'regex' ] && | print }

    reverse first name and second name

    > cat data | each { |> split | if(| length -L | chomp | [ -ge 2 ]) { | lines 1 0 | printf "%s:%s" } else { | printf "%s:nothing\n" } }

    How many c source files in current directory?

    > ls | each { |> split '\.' | lines -1 } | sort | lines '| chomp | [ = c ]' | length -L

     add comma to number

     > n=0; print 1234567890 | rows -r | scan . | each { | chomp; | if([ $n = 2 ]) { print ,; n=0 } else { ++ n } } | rows -r | pomch
     1,234,567,890

    > print 1234567890 | rows -r | (scan ... { | pomch }; print $POSTMATCH) | rows -r | join ,
     1,234,567,890
    > print 1234567890 | sub -g '(\d)(?=(?:\d\d\d)+(?!\d))' '\1,'
     1,234,567,890

    add comma between 3characters

    print if not match regex

    > ls | each { ! | match -q '^saphire' && | print }

    print from 1 to 50 number 

    > times 50 { :i: puts $(($i+1)) } | each { | printf "%02d\n" } | join , | scan '\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+'

    > times 50 { :i: ++ i; puts $i } | each { | printf "%02d\n" } | lines x10+0 -B { | join , }
