281 lines
12 KiB
Plaintext
281 lines
12 KiB
Plaintext
# testall.cmds -- one shell command per line; `testall` runs them in a scratch copy of demo/.
|
|
# ## line is printed as a heading/explanation # line is a silent comment
|
|
# Save a known-good run: testall > testall.old later: testall | diff testall.old -
|
|
# Tables used here: inventory journal expense carexpense parent female male owners
|
|
# chart ledger parttable cash X83 colors orders ed.t maillist form name
|
|
|
|
##
|
|
## ===== Selecting and arranging rows and columns =====
|
|
## row (select): keep the rows that match a condition. Column names work like awk variables.
|
|
row 'Cost > 5' < inventory
|
|
rdb select 'Description ~ /gloves/' < inventory
|
|
## column (project): pick columns in any order; a name that does not exist becomes a new empty column
|
|
column Description Cost < inventory
|
|
project Item Notes < owners
|
|
## sorttable: -n numeric, -r reverse, -f fold case
|
|
sorttable -nr Cost < inventory
|
|
## compute: calculate columns from other columns (the new column must exist, so make it with addcol)
|
|
addcol Total < inventory | compute 'Total = Amount * Cost' | column Item Total
|
|
compute 'Value = sprintf("%5.2f", Cost * Amount)' < inventory
|
|
## addcol / rename
|
|
addcol Supplier < owners
|
|
rename Owner Person < owners
|
|
## number / Number: number the rows (number: rows only, Number: rows and the head)
|
|
number < owners
|
|
Number < owners
|
|
## record: print one record (the 3rd row)
|
|
record 3 < inventory
|
|
## rmblank: drop empty rows; headon / headoff: add or strip the head
|
|
column Item Cost < inventory | rmblank
|
|
headoff < colors
|
|
headoff < colors | headon Hue
|
|
printf 'a\tb\n1\t2\n' | insertdash
|
|
## splittable: cut a table horizontally into pieces of n rows (writes colorsaa, colorsab ...)
|
|
splittable -3 colors ; ls colors* ; cat colorsab
|
|
|
|
## ===== Combining tables =====
|
|
## jointable: join on the first column; -a keeps unmatched rows, -j names the key columns
|
|
jointable inventory owners
|
|
jointable -a inventory owners
|
|
jointable -j1 Parent -j2 Name parent female
|
|
## union / intersect / difference
|
|
union expense carexpense
|
|
intersect female male
|
|
difference female male
|
|
## paste.rdb: put tables side by side
|
|
paste.rdb female male
|
|
|
|
## ===== Statistics: one result row per column =====
|
|
total Amount Value < inventory
|
|
mean Cost < inventory
|
|
maximum Cost < inventory
|
|
minimum Cost < inventory
|
|
width < inventory
|
|
precision Cost < inventory
|
|
datatype -l < inventory
|
|
widest < inventory
|
|
subtotal Date Debit Credit < journal
|
|
dbdict < inventory
|
|
schema inventory owners
|
|
tableorlist inventory maillist
|
|
|
|
## ===== Checking and displaying =====
|
|
check.rdb < inventory
|
|
printf 'a\tb\n-\t-\n1\t2\t3\n4\n' | check.rdb
|
|
display < owners
|
|
see < owners
|
|
validate 'Cost > 40 { print "expensive:", Description }' < badinventory
|
|
column Colors < orders | domain colors
|
|
domain colors black x
|
|
## fd: does Description depend on Item? (prints true/false)
|
|
fd Item Description < inventory
|
|
fd Description Cost < inventory
|
|
|
|
## ===== Text tools (arguments or standard input) =====
|
|
justify < inventory
|
|
justify -r Description < inventory
|
|
justify -c Cost < inventory
|
|
trim < inventory
|
|
compresss < inventory
|
|
pad -4 < owners
|
|
printf 'hello world\n' | cap
|
|
uppercase hello world
|
|
lowercase HELLO WORLD
|
|
printf 'one two\n' | uppercase
|
|
substitute gloves mittens colors ; cat colors
|
|
trimblank ' padded '
|
|
padstring 8 abc
|
|
padstring -8 abc
|
|
length 'how long?'
|
|
filesize inventory
|
|
ascii aA1
|
|
ascii ' '
|
|
chr 72 105
|
|
word < ed.t
|
|
cap < ed.t
|
|
blank < maillist
|
|
printf 'a\n' | prompt 'prompt text'
|
|
not false && echo 'false failed, so not succeeded'
|
|
path ls > /dev/null && echo 'ls found on the path'
|
|
## tabletom4 / tabletosed make translation files from ed.t; translate applies them
|
|
tabletom4 < ed.t
|
|
tabletosed < ed.t
|
|
tabletom4 < ed.t > ed ; echo 'I love you.' | translate ed
|
|
## uniondict builds the ed define-file out of ed.low and ed.allcap
|
|
printf 'English\tDeutsch\n-------\t-------\nlove\tliebe\n' > ed.low ; printf 'English\tDeutsch\n-------\t-------\nLOVE\tLIEBE\n' > ed.allcap ; uniondict ed
|
|
|
|
## ===== Conversions =====
|
|
tabletolist < owners
|
|
tabletolist -l < owners
|
|
tabletolist < owners | listtotable
|
|
listtotable < maillist
|
|
listtosh < maillist
|
|
tabletofix Item=4 Owner=6r < owners
|
|
tabletofix Item=4 Owner=6r < owners | fixtotable Item=1,4 Owner=5,6
|
|
tabletostruct tag owners < owners
|
|
tabletotbl < owners
|
|
tabletofact parent
|
|
tabletorule ruletable
|
|
|
|
## ===== Dates =====
|
|
## julian: dates to day numbers (arithmetic); gregorian: back again (-e European, -u US, -c day count)
|
|
julian Date < journal
|
|
julian Date < journal | gregorian Date
|
|
julian Date < journal | gregorian -e Date
|
|
## computedate: a date plus n days
|
|
computedate 890331 45
|
|
computedate 891231 1
|
|
test $(todaysdate | wc -c) -eq 7 && echo 'todaysdate prints YYMMDD'
|
|
|
|
## ===== Names that sound alike =====
|
|
soundex < name
|
|
## like: names that sound like Mann (needs the soundex table name.x, sorted by Soundex)
|
|
soundex < name > name.x ; like Mann name
|
|
hashkey 11 ABCD
|
|
hashkey 29 abcdefg
|
|
|
|
## ===== Fast access: index, search, seek =====
|
|
## search without an index scans the table (-ms); keys come from stdin
|
|
echo scales | search inventory Description
|
|
## -h leaves out the head line of the answer
|
|
printf 'Description\n-----------\nscales\n' | search -h inventory Description
|
|
## build indexes in each method: b binary, r record, i inverted, h hash
|
|
index -mr inventory ; ls inventory.r ; echo 3 | search -mr inventory
|
|
index -mi inventory Description ; ls inventory.i ; echo cl | search -mi -x inventory Description
|
|
index -mh inventory Item ; ls inventory.h ; echo 5 | search -mh inventory Item
|
|
## seek: where does the row start and end? (byte offsets)
|
|
echo 5 | seek inventory Item
|
|
echo 5 | seek -mh inventory Item
|
|
## searchtree: is Sally an ancestor of Jane? (needs a table of Parent, Child)
|
|
searchtree parent Sally Jane Parent Child
|
|
## vindex: look-up tables for ve
|
|
vindex owners Item : Owner ; vindex owners
|
|
tableorlist owners maillist
|
|
|
|
## ===== Changing tables: append, replace, delete, enter =====
|
|
## append adds a row and updates the indexes
|
|
## -h: the new row has no head line
|
|
printf '8\t1\t1.00\t1.00\tnew thing\n' | append -h -mh inventory Item ; echo 8 | search -mh inventory Item
|
|
## replace overwrites bytes from..to; take the offsets from seek
|
|
set -- $(echo 3 | seek inventory Item) ; printf '3\t6\t8.00\t48.00\tclamps\n' | replace inventory $1 $2 ; echo 3 | search inventory Item
|
|
## delete blanks the row and fixes the index
|
|
echo 4 | delete -mh inventory Item ; echo 4 | search -mh inventory Item ; echo 5 | search -mh inventory Item
|
|
## enter reads rows field by field from the terminal; -1 means one row
|
|
printf '9\n2\n3\n4\nnewer thing\n' | enter -1 inventory > /dev/null
|
|
tail -1 inventory
|
|
## lock / unlock: the second process may not lock the same bytes
|
|
lock inventory 111 10 20 0 0 ; echo "first lock status $?"
|
|
lock inventory 222 15 25 0 0 ; echo "second lock status $?"
|
|
unlock inventory 111 10 20 0 0 ; echo "unlock status $?"
|
|
lock inventory 222 15 25 0 0 ; echo "second lock now status $?" ; unlock inventory 222 15 25 0 0
|
|
## vilock edits a table under a lock; update.rdb edits records interactively
|
|
echo | vilock inventory ; echo "vilock status $?"
|
|
## update.rdb with a key on stdin and no changes (an empty line ends the dialog)
|
|
printf '3\n\n' | update.rdb inventory Item | head -8
|
|
## ve is a line editor in this version
|
|
printf 'q\n' | ve inventory | head -3
|
|
|
|
## ===== Reports and forms =====
|
|
## report fills a form with the fields of each list record (<Name>)
|
|
cat form
|
|
report form < maillist
|
|
## label prints mailing labels, letter prints form letters
|
|
label < maillist
|
|
letter form < maillist | head -5
|
|
## screen turns a form into a shell script that asks for the fields. Use a form with labels
|
|
## and every column once (entry); the report template `form` would give a blank, doubled screen.
|
|
## Run the script with: CLEAR=$(clear.rdb) sh script > table 2>&1 (the table goes to stderr)
|
|
cat entry
|
|
screen < entry
|
|
## mask draws the form itself (fields, buttons, frame) and writes the row as a table on stdout.
|
|
## It needs a terminal, so here only the picture of the form and its fields (-s) is shown.
|
|
## Try it: mask -b < maskform mask < maskform | append -h t
|
|
cat maskform
|
|
mask -s -b < maskform
|
|
## reportwriter: a sample report with page headings (the date is cut out)
|
|
reportwriter -3 Prices < inventory | grep -v 'Report Date'
|
|
## tabletom4 / tabletosed / tabletostruct were shown above
|
|
|
|
## ===== Help and the terminal =====
|
|
rdb --version
|
|
howmany
|
|
whatis row
|
|
whatwill total
|
|
helpme
|
|
commands | head -5
|
|
man -g column | head -12
|
|
termput cl | cat -v
|
|
termput cm | cat -v
|
|
tset vt100 | head -3
|
|
cursor 3 8 | cat -v
|
|
clear.rdb | cat -v
|
|
rmcore ; echo "rmcore status $?"
|
|
mkdir t1 ; cp owners t1 ; cpdir.rdb t1 t2 ; ls t2
|
|
menu < /dev/null | head -3
|
|
timesearch > /dev/null ; echo "timesearch status $?"
|
|
testsearch | tail -3
|
|
act
|
|
|
|
## ===== /act: a small accounting system =====
|
|
## (the commands work on tables in the current directory; NEXTDATE fixes the date they use)
|
|
act
|
|
## cashflow: compute the Balance column of a cash table
|
|
cashflow < cash
|
|
## tax: look up the tax for an income in a tax table
|
|
tax 20000 < X83
|
|
## explode: parts list -> all subparts with counts (part, amount)
|
|
explode 10001 2 parttable
|
|
## chartdup: look for duplicate account numbers and short names in chart
|
|
printf 'Account\tShort\n-------\t-----\n1\ta\n1\tb\n2\ta\n' > chart ; chartdup
|
|
## foot: subtotals of Debit and Credit per account in the ledger
|
|
foot
|
|
## adjust, balance, close: need a trial balance and an adjusting journal
|
|
printf 'Account\tDebit\tCredit\tFormat\tTaxline\tShort\tName\n-------\t-----\t------\t------\t-------\t-----\t----\n1010\t11178\t\tB-A\t4L01\tcash\tCash\n3010\t\t13500\tI-I\t101a\tsales\tSales\n' > trialbalance
|
|
printf 'Account\tDebit\tCredit\tFormat\tTaxline\tName\n-------\t-----\t------\t------\t-------\t----\n1010\t100\t\tB-A\t4L01\tCash\n' > journaladjust
|
|
adjust ; cat adjustedtrial
|
|
balance ; sed 2d balancesheet
|
|
NEXTDATE=870101 close ; cat journalnext
|
|
## fillform: sum the adjusted trial balance per tax line into a tax form
|
|
printf 'Taxline\tDescription\n-------\t-----------\n4L01\tCash on hand\n101a\tGross sales\n' > taxform.f1
|
|
fillform f1 ; cat f1
|
|
## calculate: compute columns of a form; f1.calc has one 'Column = expression' per line
|
|
echo 'Amount = Amount * 2' > f1.calc ; calculate f1 ; cat f1
|
|
## getjournal / consolidate: collect subsidiary journals into the general journal
|
|
printf 'Date\tAmount\tAccount\tRef\tDescription\n----\t------\t-------\t---\t-----------\n870101\t100\t4010\ts1\tshop sale\n' > journalsales
|
|
NEXTDATE=870131 getjournal journalsales
|
|
printf 'Date\tAmount\tAccount\tRef\tDescription\n----\t------\t-------\t---\t-----------\n870102\t40\t5010\tp1\tpaper\n' > journalexpense
|
|
rm journal ; consolidate 870131 ; cat journal
|
|
## payroll: calcpay sorts journalpay into ledgerpay, w2 totals per employee
|
|
printf 'Number\tGross\tFederal\tState\tNet\n------\t-----\t-------\t-----\t---\n2\t1000\t100\t50\t850\n1\t900\t90\t40\t770\n2\t1000\t100\t50\t850\n' > journalpay
|
|
calcpay ; cat ledgerpay
|
|
w2
|
|
|
|
## ===== /act: sales and stock =====
|
|
printf 'Code\tName\tPrice\n----\t----\t-----\n10010\twidget\t2.50\n10020\tgadget\t10\n' > product
|
|
printf 'Number\tCompany\tLast\n------\t-------\t----\n7\tAcme\tRoe\n' > customer
|
|
## sale: enter a sale order (customer, then code and quantity per item, then y to confirm)
|
|
printf '7\n10010\n4\n10020\n1\n\ny\n\n' | NEXTDATE=870105 sale
|
|
cat salesorder
|
|
## invoice / cstate: print an invoice or customer statement for what was sold
|
|
printf '1\n\n' | invoice
|
|
printf '7\n\n' | cstate
|
|
## bom: parts needed for everything sold (needs the table part with Code, Subpart, Count)
|
|
printf 'Code\tSubpart\tCount\n----\t-------\t-----\n10010\ts1\t3\n10020\ts1\t1\n10020\ts2\t2\n' > part
|
|
bom ; cat bom
|
|
## update.inv: change the stock of one item, with record locking (INV names the table)
|
|
cp inventory inv ; printf '7\n9\n\n' | INV=inv update.inv | tail -n +2
|
|
grep '^7' inv
|
|
|
|
## ===== Choosing rows on the terminal =====
|
|
## pick shows a table, lets you scroll, filter (/) and mark rows (Space, -m), and writes the
|
|
## chosen rows as a table, so it can sit in a pipe. It needs a terminal; -k feeds the keys instead.
|
|
## Try it: pick -m < inventory | total Amount Value
|
|
## mark the 2nd and 5th row (down, space, down, down, space) and finish with enter
|
|
pick -m -k 'down space down down space enter' < inventory
|
|
## the same chosen rows go on into total
|
|
pick -m -k 'down space down down space enter' < inventory | total Amount Value
|
|
## filter with / (type, enter), then choose the row that is left
|
|
pick -k '/clamps enter enter' < inventory
|
|
## Esc cancels: nothing on stdout, exit status 1
|
|
pick -k esc < inventory ; echo "status $?"
|