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 statment.
    ||              If a statment return code is not 0, saphire evals next statment.
    &               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

    > print red | global futatuna
    > puts "share $(global futatuna) aznable"
    shar red aznable

    > print red | global futatuna
    > puts 'share $(global futatuna) aznable'
    share $(global 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.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 

    print 1 | var a

    The reference method is

    $(var a)

    $(var a) is quoted with characters used by saphire.
    $$(var a) is not quoted.

    >print "a;b" | var a; puts $(var a)
    a;b

    ; is quoted.

    >print "a;b" | var a; puts $$(var a)
    command not found

    ; is not quoted.

    > print 1 | var a; puts $(var a)
    1
    > print b | var b; puts a$(var b)c
    abc
    > print 1 | var a; print a | var i; puts $(var $(var i))
    1
    > print 1 | var a; def fun { print 2 | var a; puts $(var a); }; fun; puts $(var a)
    2
    1
    > print 1  | var a; puts $(var a)
    1
    > ls / | var a b c; var a b c | join
    bin boot cdrom

    local variable is initialized at each commandline.

    > print 1 | var a
    > var a | pomch

    > print 1 | var a ; var a | pomch
    1

    You should use a global variable 

    > print 1 | global a
    > global a | pomch
    1

    global variables can be common used in all area.

    > print 1 |  global a; def fun { puts $(var a) }; def fun2 { puts $(var a) }; fun; fun2
    1
    1

    > puts aaa | global a; puts $(var a)
    aaa

    environment variables are same bash or other shells.

    >print 1 | export a; export a | pomch
    1

    > ls / | export a; export a | pomch
    bin

    You can use alphabets and _ with variable name.

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

    >print abc | var a; puts $(var a | rows 0)
    a

    >print abc | var a; puts $(var a | rows 0..1)
    ab

    >print abc | var a; puts $(var a | rows 0..-2)
    ab

    >print abc | var a; puts $(var a | rows 0 0 0 1)
    aaab

    >print abcdefg | var a; puts $(var a | rows 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.

    > print a\nb\nc | ary A
    > Ary A 0
    a
    > ary A | lines 1..2
    b
    c
    > ary A | lines 1 2
    b
    c
    > ary A | lines 0 2 2 0..-1
    a
    c
    c
    a
    b
    c

    >ary A | lines 2..1
    c
    b

    > ary A
    a
    b
    c
    > ary A | join ,
    a,b,c
    > ary -s A
    3
    > ary A | lines 1..2 | join
    b c

    > cat main.c | ary A
    > ary A | lines 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.

    >print key\nabc\nあ\ndef | hash a
    >hash a key
    abc

    >hash a あ
    def

    >hash a
    key
    abc
    あ
    def

    >hash a | join ,
    key,abc,あ,def

    >hash a | lines \*2
    abc  # getting items
    def

    >hash 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.

    >print abc | var a; puts aaa@(var a)
    aaa
    abc

    same as

    >print abc | var a; puts aaa abc

    the diference

    >print abc | var a; puts aaa$(var a)
    aaaabc

    If you treat big files, you should use @.

    > cat big_file.txt | each{ | split | ary a; puts @(ary a 0) @(ary a 1) }

    it's faster than

    > cat big_file.txt | each{ | split | ary a; puts $(ary a 0) $(ary a 1) }

    and the other situation is

    > cat big_file.txt | ary a; puts $(ary a)

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

    > cat big_file.txt | ary a; puts @(ary a)

    is not stopped because @(ary 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 a; cp @a /tmp
    happens err because all element are expanded one argument.

    > ls | ary 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 $(var RCODE)
    0

    >false; puts $(var RCODE)
    1

    ! statment

    ! reverses return code

    > ! puts aaa\nbbb | match -q a; puts $(var 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

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

1.7.1 STDIN pipe

    | reads from STDIN depeding on context.

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

    > ls | if( | [ -re A.+ ] ) { | print }
    AUTHOR

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 $(var a) $(var 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}

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

    > print 1 | var a; vim a.sh
    if ([ $(var a) = 1 ]) {
        puts yes
    } else {
        puts no
    }
    > load a.sh | uc
    YES

    you can use linefield in blocks

    while statment

    while (condition) {statment}

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

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

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

    puts max length of main.c is $(var 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 $(ary -s ARGV); puts $(ary ARGV 0) $(ARGV 1); puts $(ary ARGV | join \n) }; fun a b c
    3
    a b
    a
    b
    c

    >vim a.sh
    def fun {
        print 2 | var a
        print 3 | global b
        puts $(var a) $(global b)
    }

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

    ARGV is argument array.

    there is special statment

    > def fun(_ARGV) { puts $(ary -s _ARGV); puts $(ary _ARGV | join , ) }; 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) {
        print 1 | var NR
        while(<> |>) {
            yeild 0

            ++ NR
        }
    }

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

   > print 1 | var a; ls -al | each { |> var line; puts "$(var a):$(var line)"; ++ a }; puts $(var 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 "$(global 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 ]; var PREMATCH MATCH POSTMATCH| join ,
    ab,c,defg

    >[ abcdefg -re '(.+)(c)(.+)' ]; var 1 2 3 | join ,
    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 ]; var RCODE
    0

    >print aaa | [ ! = aaa ]; var 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 -I name name ...
    | var name name ...

    definitio of localvariable, which is initialized from STDIN.

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

    var name name
    output of local variables. If a local variable is not defined, outoput null string or with -n defined as 0 and output.

    -nc no chomp

    -f "field characters" set fields
    -nc no chomp
    -I read from STDIN
    -p enable output
    -n If a local variable is not defined, output and defined as 0

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

    definition of global variable with initializing from STDIN

    global name name
    output of global variables. If a global variable is not defined, outoput null string or with -n is defined as 0 and output.

    -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
    -n If a global variable is not defined, output and defined as 0

    export -I name name name
    | export name name ...

    definition of environment variable

    export name name
    output of export variables. If a variable is not defined, outoput null string or with -n defined as 0 and output.

    -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
    -n If a variable is not defined, output and defined as 0

    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 name name2 name3 ..

    referce

    ary -I
    | ary name

    -s output size of the array
    -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 '..(.).(.).'; var 1 2| join ,
    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.

    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

    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
    you can use close command to close this opened file.

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

    close [file name]
    close -a

    close a file which is opend by read command
    close all files with -a

    cd directory

    move directory

    | selector

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

    hit ENTER --> select
    hit SPACE --> multiple select
    hit a --> all marks reverse

    -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 name 
    hash name key

    refference

    hash name
    | hash_new name

    make hash

    > print key value key2 value2 key3 value3 | split | hash a
    > puts $(hash 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 { [ $(var a) -slt $(var b) ] } to sort

    1st line of STDIN pipe is left one line
    2nd line of STDIN pipe is right one line

    > ls | sort
    > ls | sort { | var a b; [ $(var a) -slt $(var b) ] }


    > ls | sort { | var a b; [ $(var a) -sgt $(var b) ] }

    > ary ARGV | sort { | var a b; [ $(var a) -slt $(var b) ] } | ary ARGV2
    > ls -al | sort { | each { | split | lines 8 } | var a b; [ $(var a) -slt $(var b) ] }

    sort of 9th field

    ++ [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

    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 $(var i) }
    0:main.c
    1:sub.c

    foreach string...string block

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

    >print a\nb\nc | ary A
    >foreach $(ary A | join " ") { | pomch }
    a
    b
    c

    > print a\nb\nc | ary A
    >foreach @@(ary 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

    You can get count number as a STDIN pipe

    > times 3 { | pomch }
    0
    1
    2
    step [init num] [final num] [aditional num] [ block ]

    >step 3 10 3 { | pomch }
    3
    6
    9

    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

    >print a\nb\nc | ary A
    >for a in $(ary A | join " ") { puts @(var a) }
    a
    b
    c

    >print a\nb\nc | ary A
    >for a in @@(ary A) { puts @(var a) }
    a
    b
    c

    case value regex1 block1 regex2 block2...

    >print 1 | var a; case $(var a) 0 { puts a } 1 { puts b } 2 { puts c } 3 { puts d }
    b

sample

    uppercase head of file names

    ls | each { | rows 0 { | uc } 1..-1 { | pomch } | chomp }

    egrep

    ls | each { | match -q 'regex' && | print }

    cat -n

    ls | each { | add $(++ nr; var nr): }

    exchange first name and second name

    cat data | each { | split | lines 1 0 | printf "%s:%s" }

    How many c files in current directory?

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

    or

    ls *.c | wc -l

     add comma to number

    > print 1234567890 | sub -g '(\d)(?=(?:\d\d\d)+(?!\d))' '\1,'
     1,234,567,890

