## ## ===== 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 Item Amount Cost Value Description ---- ------ ---- ----- ----------- 3 5 8.00 40.00 clamps 6 89 14.75 1312.75 bunsen burners 7 5 175.00 875.00 scales $ rdb select 'Description ~ /gloves/' < inventory Item Amount Cost Value Description ---- ------ ---- ----- ----------- 1 3 5.00 15.00 rubber gloves ## column (project): pick columns in any order; a name that does not exist becomes a new empty column $ column Description Cost < inventory Description Cost ----------- ---- rubber gloves 5.00 test tubes 0.50 clamps 8.00 plates 1.98 cleaning cloth 2.45 bunsen burners 14.75 scales 175.00 $ project Item Notes < owners Item Notes ---- ----- 1 3 6 ## sorttable: -n numeric, -r reverse, -f fold case $ sorttable -nr Cost < inventory Item Amount Cost Value Description ---- ------ ---- ----- ----------- 7 5 175.00 875.00 scales 6 89 14.75 1312.75 bunsen burners 3 5 8.00 40.00 clamps 1 3 5.00 15.00 rubber gloves 5 99 2.45 242.55 cleaning cloth 4 23 1.98 45.54 plates 2 100 0.50 50.00 test tubes ## 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 Item Total ---- ----- 1 15 2 50 3 40 4 45.54 5 242.55 6 1312.75 7 875 $ compute 'Value = sprintf("%5.2f", Cost * Amount)' < inventory Item Amount Cost Value Description ---- ------ ---- ----- ----------- 1 3 5.00 15.00 rubber gloves 2 100 0.50 50.00 test tubes 3 5 8.00 40.00 clamps 4 23 1.98 45.54 plates 5 99 2.45 242.55 cleaning cloth 6 89 14.75 1312.75 bunsen burners 7 5 175.00 875.00 scales ## addcol / rename $ addcol Supplier < owners Item Owner Supplier ---- ----- -------- 1 ann 3 bob 6 cy $ rename Owner Person < owners Item Person ---- ------ 1 ann 3 bob 6 cy ## number / Number: number the rows (number: rows only, Number: rows and the head) $ number < owners number Item Owner ------ ---- ----- 1 1 ann 2 3 bob 3 6 cy $ Number < owners Number Item Owner ------ ---- ----- 1 1 ann 2 3 bob 3 6 cy ## record: print one record (the 3rd row) $ record 3 < inventory Item Amount Cost Value Description ---- ------ ---- ----- ----------- 3 5 8.00 40.00 clamps ## rmblank: drop empty rows; headon / headoff: add or strip the head $ column Item Cost < inventory | rmblank Item Cost ---- ---- 1 5.00 2 0.50 3 8.00 4 1.98 5 2.45 6 14.75 7 175.00 $ headoff < colors black blue carmel green purple red silver white $ headoff < colors | headon Hue Hue --- black blue carmel green purple red silver white $ printf 'a\tb\n1\t2\n' | insertdash a b - - 1 2 ## splittable: cut a table horizontally into pieces of n rows (writes colorsaa, colorsab ...) $ splittable -3 colors ; ls colors* ; cat colorsab colors colorsaa colorsab colorsac Colors ------ green purple red ## ===== Combining tables ===== ## jointable: join on the first column; -a keeps unmatched rows, -j names the key columns $ jointable inventory owners Item Amount Cost Value Description Owner ---- ------ ---- ----- ----------- ----- 1 3 5.00 15.00 rubber gloves ann 3 5 8.00 40.00 clamps bob 6 89 14.75 1312.75 bunsen burners cy $ jointable -a inventory owners Item Amount Cost Value Description Owner ---- ------ ---- ----- ----------- ----- 1 3 5.00 15.00 rubber gloves ann 2 100 0.50 50.00 test tubes 3 5 8.00 40.00 clamps bob 4 23 1.98 45.54 plates 5 99 2.45 242.55 cleaning cloth 6 89 14.75 1312.75 bunsen burners cy 7 5 175.00 875.00 scales $ jointable -j1 Parent -j2 Name parent female Parent Child ------ ----- Sally Fred ## union / intersect / difference $ union expense carexpense Date Amount Account Ref Description ---- ------ ------- --- ----------- 820107 14.00 meal v meal with jones 820113 101.62 car v car repairs 820114 81.80 insur c car insurance allstate 820113 101.62 car v car repairs 820114 81.80 insur c car insurance allstate 820114 93.00 car c car registration dmv $ intersect female male Name ---- $ difference female male Name ---- Jane Sally ## paste.rdb: put tables side by side $ paste.rdb female male Name Name ---- ---- Jane Fred Sally Mike ## ===== Statistics: one result row per column ===== $ total Amount Value < inventory Item Amount Cost Value Description ---- ------ ---- ----- ----------- 324 2580.84 $ mean Cost < inventory Item Amount Cost Value Description ---- ------ ---- ----- ----------- 29.67 $ maximum Cost < inventory Item Amount Cost Value Description ---- ------ ---- ----- ----------- 175.00 $ minimum Cost < inventory Item Amount Cost Value Description ---- ------ ---- ----- ----------- 0.50 $ width < inventory Item Amount Cost Value Description ---- ------ ---- ----- ----------- 4 6 6 7 14 $ precision Cost < inventory Item Amount Cost Value Description ---- ------ ---- ----- ----------- 2 $ datatype -l < inventory Item Amount Cost Value Description ---- ------ ---- ----- ----------- 1 3 5.00 15.00 rubber gloves 2 100 0.50 50.00 test tubes 3 5 8.00 40.00 clamps 4 23 1.98 45.54 plates 5 99 2.45 242.55 cleaning cloth 6 89 14.75 1312.75 bunsen burners 7 5 175.00 875.00 scales ---- ------ ---- ----- ----------- 0 0 2 2 -1 $ widest < inventory Item Amount Cost Value Description ---- ------ ---- ----- ----------- 4 6 6 7 14 $ subtotal Date Debit Credit < journal Date Account Debit Credit Description ---- ------- ----- ------ ----------- 861222 25000 25000 861223 10000 10000 861224 30000 30000 $ dbdict < inventory field name ----- ---- 1 Item 2 Amount 3 Cost 4 Value 5 Description $ schema inventory owners Table Field Name ----- ----- ---- inventory 1 Item inventory 2 Amount inventory 3 Cost inventory 4 Value inventory 5 Description owners 1 Item owners 2 Owner $ tableorlist inventory maillist table list ## ===== Checking and displaying ===== $ check.rdb < inventory $ printf 'a\tb\n-\t-\n1\t2\t3\n4\n' | check.rdb check.rdb: Columns (3) do not equal headline columns (2) in row 1 (line 3). 1 2 3 check.rdb: Columns (1) do not equal headline columns (2) in row 2 (line 4). 4 $ display < owners Item Owner ---- ----- 1 ann 3 bob 6 cy $ see < owners Item^IOwner$ ----^I-----$ 1^Iann$ 3^Ibob$ 6^Icy$ $ validate 'Cost > 40 { print "expensive:", Description }' < badinventory Item# Onhand Cost Value Description ----- ------ ---- ----- ----------- expensive: rubber gloves 1 3 50 150 rubber gloves expensive: test tubes 2 100 X 500 test tubes expensive: clamps 3 -5 80 -400 clamps 4 23 19 437 plates 5 -99 24 -2376 cleaning cloth $ column Colors < orders | domain colors Colors ------ farble yellow $ domain colors black x x ## fd: does Description depend on Item? (prints true/false) $ fd Item Description < inventory true $ fd Description Cost < inventory true ## ===== Text tools (arguments or standard input) ===== $ justify < inventory Item Amount Cost Value Description ---- ------ ------ ------- -------------- 1 3 5.00 15.00 rubber gloves 2 100 0.50 50.00 test tubes 3 5 8.00 40.00 clamps 4 23 1.98 45.54 plates 5 99 2.45 242.55 cleaning cloth 6 89 14.75 1312.75 bunsen burners 7 5 175.00 875.00 scales $ justify -r Description < inventory Item Amount Cost Value Description ---- ------ ---- ----- -------------- 1 3 5.00 15.00 rubber gloves 2 100 0.50 50.00 test tubes 3 5 8.00 40.00 clamps 4 23 1.98 45.54 plates 5 99 2.45 242.55 cleaning cloth 6 89 14.75 1312.75 bunsen burners 7 5 175.00 875.00 scales $ justify -c Cost < inventory Item Amount Cost Value Description ---- ------ ------ ----- ----------- 1 3 5.00 15.00 rubber gloves 2 100 0.50 50.00 test tubes 3 5 8.00 40.00 clamps 4 23 1.98 45.54 plates 5 99 2.45 242.55 cleaning cloth 6 89 14.75 1312.75 bunsen burners 7 5 175.00 875.00 scales $ trim < inventory Item Amount Cost Value Description ---- ------ ------ ------- -------------- 1 3 5.00 15.00 rubber gloves 2 100 0.50 50.00 test tubes 3 5 8.00 40.00 clamps 4 23 1.98 45.54 plates 5 99 2.45 242.55 cleaning cloth 6 89 14.75 1312.75 bunsen burners 7 5 175.00 875.00 scales $ compresss < inventory Item Amount Cost Value Description ---- ------ ---- ----- ----------- 1 3 5.00 15.00 rubber gloves 2 100 0.50 50.00 test tubes 3 5 8.00 40.00 clamps 4 23 1.98 45.54 plates 5 99 2.45 242.55 cleaning cloth 6 89 14.75 1312.75 bunsen burners 7 5 175.00 875.00 scales $ pad -4 < owners Item Owner ---- ----- 1 ann 3 bob 6 cy $ printf 'hello world\n' | cap Hello World $ uppercase hello world HELLO WORLD $ lowercase HELLO WORLD hello world $ printf 'one two\n' | uppercase ONE TWO $ substitute gloves mittens colors ; cat colors Colors ------ black blue carmel green purple red silver white $ trimblank ' padded ' padded $ padstring 8 abc abc $ padstring -8 abc abc $ length 'how long?' 9 $ filesize inventory 263 $ ascii aA1 97 65 49 $ ascii ' ' 32 $ chr 72 105 Hi $ word < ed.t Deutch English I Ich dich liebe love widgit you $ cap < ed.t English Deutch ------- ------ I Ich Love Liebe You Dich Widgit $ blank < maillist Number Name Company Street City State ZIP Phone Number Name Company Street City State ZIP Phone $ printf 'a\n' | prompt 'prompt text' prompt text $ not false && echo 'false failed, so not succeeded' false failed, so not succeeded $ path ls > /dev/null && echo 'ls found on the path' ls found on the path ## tabletom4 / tabletosed make translation files from ed.t; translate applies them $ tabletom4 < ed.t define(I,Ich) define(love,liebe) define(you,dich) $ tabletosed < ed.t s/I/Ich/g s/love/liebe/g s/you/dich/g $ tabletom4 < ed.t > ed ; echo 'I love you.' | translate ed Ich liebe dich. ## 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 define(love,liebe) define(Love,Liebe) define(LOVE,LIEBE) ## ===== Conversions ===== $ tabletolist < owners Item 1 Owner ann Item 3 Owner bob Item 6 Owner cy $ tabletolist -l < owners Item 1 Owner ann Item 3 Owner bob Item 6 Owner cy $ tabletolist < owners | listtotable Item Owner ---- ----- 1 ann 3 bob 6 cy $ listtotable < maillist Number Name Company Street City State ZIP Phone ------ ---- ------- ------ ---- ----- --- ----- 1 Ronald McDonald McDonalds 123 Mac Attack Memphis TENN 30000 (111) 222-3333 2 Chiquita Banana United Brands Uno Avenido de la Reforma San Jose Costa Rica 123456789 1234 $ listtosh < maillist Number='1' Name='Ronald McDonald' Company='McDonalds' Street='123 Mac Attack' City='Memphis' State='TENN' ZIP='30000' Phone='(111) 222-3333' Number='2' Name='Chiquita Banana' Company='United Brands' Street='Uno Avenido de la Reforma' City='San Jose' State='Costa Rica' ZIP='123456789' Phone='1234' $ tabletofix Item=4 Owner=6r < owners 1 ann 3 bob 6 cy $ tabletofix Item=4 Owner=6r < owners | fixtotable Item=1,4 Owner=5,6 Item Owner ---- ----- 1 ann 3 bob 6 cy $ tabletostruct tag owners < owners struct tag { char *Item; char *Owner; } owners [] = { "1","ann" }, { "3","bob" }, { "6","cy" } ; $ tabletotbl < owners .TS n l. Item Owner _ 1 ann 3 bob 6 cy .TE $ tabletofact parent parent(Sally,Fred). parent(Mike,Fred). parent(Fred,Jane). $ tabletorule ruletable mother(X,Y) :- female(X), parent(X,Y). ## ===== Dates ===== ## julian: dates to day numbers (arithmetic); gregorian: back again (-e European, -u US, -c day count) $ julian Date < journal Date Account Debit Credit Description ---- ------- ----- ------ ----------- 1752827 101 25000 cash from loan 1752827 211.1 25000 loan number #378-14 Bank Amerigold 1752828 150.1 10000 test equipment from Zarkoff 1752828 101 5000 cash payment 1752828 211.2 5000 note payable to Zarkoff Equipment 1752829 130 30000 inventory - parts from CCPSC 1752829 201.1 15000 accounts payable to CCPSC 1752829 101 15000 cash payment to CCPSC for parts $ julian Date < journal | gregorian Date Date Account Debit Credit Description ---- ------- ----- ------ ----------- 861222 101 25000 cash from loan 861222 211.1 25000 loan number #378-14 Bank Amerigold 861223 150.1 10000 test equipment from Zarkoff 861223 101 5000 cash payment 861223 211.2 5000 note payable to Zarkoff Equipment 861224 130 30000 inventory - parts from CCPSC 861224 201.1 15000 accounts payable to CCPSC 861224 101 15000 cash payment to CCPSC for parts $ julian Date < journal | gregorian -e Date Date Account Debit Credit Description ---- ------- ----- ------ ----------- 22/12/86 101 25000 cash from loan 22/12/86 211.1 25000 loan number #378-14 Bank Amerigold 23/12/86 150.1 10000 test equipment from Zarkoff 23/12/86 101 5000 cash payment 23/12/86 211.2 5000 note payable to Zarkoff Equipment 24/12/86 130 30000 inventory - parts from CCPSC 24/12/86 201.1 15000 accounts payable to CCPSC 24/12/86 101 15000 cash payment to CCPSC for parts ## computedate: a date plus n days $ computedate 890331 45 890515 $ computedate 891231 1 900101 $ test $(todaysdate | wc -c) -eq 7 && echo 'todaysdate prints YYMMDD' todaysdate prints YYMMDD ## ===== Names that sound alike ===== $ soundex < name Name Soundex ---- ------- Abraham A165 Abraham A165 Adams A352 Ackerman A265 Manis M520 Mann M500 Miller M460 Moon M500 ## like: names that sound like Mann (needs the soundex table name.x, sorted by Soundex) $ soundex < name > name.x ; like Mann name Name ---- Mann Moon $ hashkey 11 ABCD 2 $ hashkey 29 abcdefg 4 ## ===== Fast access: index, search, seek ===== ## search without an index scans the table (-ms); keys come from stdin $ echo scales | search inventory Description Item Amount Cost Value Description ---- ------ ---- ----- ----------- 7 5 175.00 875.00 scales ## -h leaves out the head line of the answer $ printf 'Description\n-----------\nscales\n' | search -h inventory Description 7 5 175.00 875.00 scales ## build indexes in each method: b binary, r record, i inverted, h hash $ index -mr inventory ; ls inventory.r ; echo 3 | search -mr inventory inventory.r Item Amount Cost Value Description ---- ------ ---- ----- ----------- 3 5 8.00 40.00 clamps $ index -mi inventory Description ; ls inventory.i ; echo cl | search -mi -x inventory Description inventory.i Item Amount Cost Value Description ---- ------ ---- ----- ----------- 3 5 8.00 40.00 clamps 5 99 2.45 242.55 cleaning cloth $ index -mh inventory Item ; ls inventory.h ; echo 5 | search -mh inventory Item inventory.h Item Amount Cost Value Description ---- ------ ---- ----- ----------- 5 99 2.45 242.55 cleaning cloth ## seek: where does the row start and end? (byte offsets) $ echo 5 | seek inventory Item 172 204 0 8 $ echo 5 | seek -mh inventory Item 172 204 113 122 ## searchtree: is Sally an ancestor of Jane? (needs a table of Parent, Child) $ searchtree parent Sally Jane Parent Child TRUE ## vindex: look-up tables for ve $ vindex owners Item : Owner ; vindex owners == Item-A Item ---- 1 3 6 == Item-B Item Owner ---- ----- 1 ann 3 bob 6 cy $ tableorlist owners maillist table list ## ===== 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 Item Amount Cost Value Description ---- ------ ---- ----- ----------- 8 1 1.00 1.00 new thing ## 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 Item Amount Cost Value Description ---- ------ ---- ----- ----------- 3 6 8.00 48.00 clamps ## 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 Item Amount Cost Value Description ---- ------ ---- ----- ----------- Item Amount Cost Value Description ---- ------ ---- ----- ----------- 5 99 2.45 242.55 cleaning cloth ## 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 9 2 3 4 newer thing ## lock / unlock: the second process may not lock the same bytes $ lock inventory 111 10 20 0 0 ; echo "first lock status $?" first lock status 0 $ lock inventory 222 15 25 0 0 ; echo "second lock status $?" lock: inventory: bytes 15-25 are locked by process 111 second lock status 1 $ unlock inventory 111 10 20 0 0 ; echo "unlock status $?" unlock status 0 $ lock inventory 222 15 25 0 0 ; echo "second lock now status $?" ; unlock inventory 222 15 25 0 0 second lock now status 0 ## vilock edits a table under a lock; update.rdb edits records interactively $ echo | vilock inventory ; echo "vilock status $?" vilock status 0 ## 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 > -- record 3 of 8 1 Item 3 2 Amount 6 3 Cost 8.00 4 Value 48.00 5 Description clamps > -- record 4 of 8 1 Item 5 ## ve is a line editor in this version $ printf 'q\n' | ve inventory | head -3 -- inventory: record 1 of 9 1 Item 1 2 Amount 3 ## ===== Reports and forms ===== ## report fills a form with the fields of each list record () $ cat form < City >, Hi < Name >: $ report form < maillist Ronald McDonald McDonalds 123 Mac Attack Memphis, TENN 30000 Hi Ronald McDonald: Chiquita Banana United Brands Uno Avenido de la Reforma San Jose, Costa Rica 123456789 Hi Chiquita Banana: ## label prints mailing labels, letter prints form letters $ label < maillist Ronald McDonald McDonalds 123 Mac Attack Memphis, TENN 30000 Chiquita Banana United Brands Uno Avenido de la Reforma San Jose, Costa Rica 123456789 $ letter form < maillist | head -5 Ronald McDonald McDonalds 123 Mac Attack Memphis, TENN 30000 ## screen turns a form into a shell script that asks for the fields $ screen < form | head -6 : paint crt screen exec 1>/dev/tty cat < /dev/null ; echo "timesearch status $?" timesearch status 0 $ testsearch | tail -3 -mh: ok (200 rows found) -mi: ok (200 rows found) -mr: ok (200 rows found) $ act act adjust balance bom calcpay calculate cashflow chartdup close consolidate cstate explode fillform foot getjournal invoice sale tax update.inv w2 ## ===== /act: a small accounting system ===== ## (the commands work on tables in the current directory; NEXTDATE fixes the date they use) $ act act adjust balance bom calcpay calculate cashflow chartdup close consolidate cstate explode fillform foot getjournal invoice sale tax update.inv w2 ## cashflow: compute the Balance column of a cash table $ cashflow < cash Date Amount Balance Description ---- ------ ------- ----------- 890101 512 512 current balance 890101 -450 62 rent check 890101 1000 1062 pay check 890115 -300 762 estimated tax payment ## tax: look up the tax for an income in a tax table $ tax 20000 < X83 3369 ## explode: parts list -> all subparts with counts (part, amount) $ explode 10001 2 parttable Part Amount ---- ------ 10001 2 10010 6 10020 8 10100 52 ## 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 Duplicate Account numbers in chart. See chart.Account 1 a 1 b Duplicate Short names in chart. See chart.Short 1 a 2 a ## foot: subtotals of Debit and Credit per account in the ledger $ foot Account Date Debit Credit ------- ---- ----- ------ 101 820102 25000 101 820103 5000 101 820104 15000 ------- ---- ----- ------ 101 15000 30000 130 820104 30000 ------- ---- ----- ------ 130 30000 0 150.1 820103 10000 ------- ---- ----- ------ 150.1 10000 0 201.1 820104 15000 ------- ---- ----- ------ 201.1 15000 0 211.1 820102 25000 ------- ---- ----- ------ 211.1 0 25000 211.2 820103 5000 ------- ---- ----- ------ 211.2 0 5000 ## 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 Account Debit Credit Format Taxline Short Name ------- ----- ------ ------ ------- ----- ---- 1010 11278 B-A 4L01 cash Cash 3010 13500 I-I 101a sales Sales $ balance ; sed 2d balancesheet Company Balancesheet 11278 Cash ----- ------------------------ 11278 Total Assets 13500 Retained Earnings (Profit) ------ -------------------------- 13500 Total Liabilities and Equity $ NEXTDATE=870101 close ; cat journalnext Account Date Debit Credit Ref Description ------- ---- ----- ------ --- ----------- 1010 870101 11278 jl brought forward 4997 870101 11278 jl brought forward ## 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 Taxline Amount Description ------- ------ ----------- 4L01 11278 Cash on hand 101a 13500 Gross sales ## calculate: compute columns of a form; f1.calc has one 'Column = expression' per line $ echo 'Amount = Amount * 2' > f1.calc ; calculate f1 ; cat f1 Taxline Amount Description ------- ------ ----------- 4L01 22556 Cash on hand 101a 27000 Gross sales ## 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 Date Amount Account Ref Description ---- ------ ------- --- ----------- 870131 100.00 s1 sales from 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 Date Account Debit Credit Ref Description ---- ------- ----- ------ --- ----------- 870102 5010 40 p1 paper 870101 4010 100 s1 shop sale 870131 1010 40 double-entry 870131 1010 100 double-entry ## 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 Number Gross Federal State Net ------ ----- ------- ----- --- 1 900 90 40 770 2 1000 100 50 850 2 1000 100 50 850 $ w2 Number Gross Federal State Net ------ ----- ------- ----- --- 1 900 90 40 770 2 2000 200 100 1700 ## ===== /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 Enter Customer Number (? for new, /string search, Return to exit) Mailing Address for Customer Number 7 Roe Acme Code (Return when done): Qty: Code (Return when done): Qty: Code (Return when done): Number Cust Date Shipped Gross Tax Total ------ ---- ---- ------- ----- --- ----- 1 7 870105 0 20.00 1.00 21.00 Is this correct? (y, n) Enter Customer Number (? for new, /string search, Return to exit) $ cat salesorder Number Cust Date Shipped Gross Tax Total ------ ---- ---- ------- ----- --- ----- 1 7 870105 0 20.00 1.00 21.00 ## invoice / cstate: print an invoice or customer statement for what was sold $ printf '1\n\n' | invoice Please enter order number (or Return to exit): Invoice ------- Company Order Number 1 Date Ordered 870105 Date Shipped 0 Mailing Address for Customer Number 7 Roe Acme Order Number Code Backord Qty Price Total Name ----- ------ ---- ------- --- ----- ----- ---- 1 1 10010 10 4 2.50 10.00 widget 1 2 10020 10 1 10 10.00 gadget Gross 20.00 Tax 1.00 Total 21.00 Please enter order number (or Return to exit): $ printf '7\n\n' | cstate Please enter customer number (or all or Return to exit): Customer Statement ------------------ Mailing Address for Customer Number 7 Roe Acme Now Due and Payable is your balance of: 21.00 Details of Your Orders and Payments Cust Date Amount Ref ---- ---- ------ --- 7 870105 -21.00 1 -21.00 Please enter customer number (or all or Return to exit): ## 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 Code Qty ---- --- s1 13 s2 2 ## 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 Item Number: (or hit Return key to exit.) Item=7 Amount=5 Cost=175.00 Value=875.00 Description=scales Amount Amount: Item Number: (or hit Return key to exit.) $ grep '^7' inv 7 9 175.00 1575 scales