- doc/handbuch.txt: OCR-Text des COHERENT-/rdb-Handbuchs - demo/handbuch/ und test/handbuch_test.rb: Beispiele aus dem Lehrbuchteil, mise run test führt sie mit aus - search/seek: Schlüsselspalten aus dem Kopf der Schlüsseltabelle - gregorian -u ohne führende Null im Monat, mean ganzzahlig ohne .00 - Mit justify aufgefüllte Spaltennamen werden wieder gefunden - coherent.pdf in .gitignore
20132 lines
605 KiB
Plaintext
20132 lines
605 KiB
Plaintext
COHERENT /rdb Relational Database Manager (Mark Williams Company)
|
||
Text per OCR (tesseract) aus coherent.pdf. Nicht korrigiert: Tabulatoren fehlen, Tabellen und Zeichen können falsch sein.
|
||
Im Zweifel gilt der Scan. Buchseite = PDF-Seite - 10.
|
||
|
||
==== PDF-Seite 1 ====
|
||
COHERENT
|
||
|
||
[rd Relational
|
||
Database
|
||
Manager
|
||
|
||
==== PDF-Seite 2 ====
|
||
Copyright © 1992 by Mark Williams Company.
|
||
Copyright © 1992 by Revolutionary Software, Inc.
|
||
|
||
All rights reserved.
|
||
|
||
This publication conveys information that is the property of Mark Williams Company and
|
||
Revolutionary Software, Inc. It shall not be copied, reproduced or duplicated in whole or in
|
||
part without the express written permission of Mark Williams Company and Revolutionary
|
||
Software, Inc. Mark Williams Company and Revolutionary Software, Inc. make no warranty of
|
||
any kind with respect to this material and disclaim any implied warranties of merchantability
|
||
or fitness for any particular purpose.
|
||
|
||
COHERENT is a trademark of Mark Williams Company. /rdb and /act are trademarks of Rod
|
||
Manis. UNIX is a trademark of AT&T. MS-DOS is a trademark of Microsoft Corporation.
|
||
dBASE is a trademark of Ashton-Tate. All other products are trademarks or registered
|
||
trademarks of the respective holders.
|
||
|
||
Revision 1 Printing54321
|
||
Published by Mark Williams Company. 60 Revere Drive. Northbrook, Illinois 60062.
|
||
|
||
E-mail: uunet!mwe!support (Technical Support)
|
||
support@mwc.com
|
||
uunet!mwe!sales (General Information)
|
||
sales@mwe.com
|
||
|
||
BIX: join mwce
|
||
|
||
CompuServ: 76256 .427
|
||
|
||
This manual was written under the COHERENT operating system, using the MicroEMACS and
|
||
ed text editors. Text formatting was performed by the COHERENT edition of the troff text
|
||
formatter, using its PostScript output function. Typesetting of this manual, from the table of
|
||
contents through the index, was performed by one script written in the COHERENT Korn
|
||
shell. Camera-ready copy was printed on a Hewlett-Packard LaserJet IIP printer using the
|
||
Pacific Page PostScript cartridge.
|
||
|
||
Printed in the U.S.A.
|
||
|
||
==== PDF-Seite 3 ====
|
||
Table of Contents
|
||
|
||
Le Introductions occ eo ob ira oo 0 eetaa © ww wees © wo where ee 8 oe meee oe 1
|
||
Installing /rdb. «6 6. ee ee ee ee te ee 1
|
||
European Keyboards... . 2... 0. eee eee 1
|
||
Data Bases and COHERENT ....-- eee eee eerie 2
|
||
Tables and COHERENT... ...-----+ eee 2
|
||
Operating Systems that Support COHERENT-Style Environments 3
|
||
Applications Development... 6.6 6s eee ee ee ee ee ee ee eee 3
|
||
Data Bases nici css sieves oo aeons % & 8 Ewe 3
|
||
COHERENT Environment . . 3
|
||
Fourth Generation Systems . 4
|
||
Attempts at a Definition . . . 4
|
||
Previous Generations. ....... 4
|
||
Data Structures in the Data... . 5
|
||
A Revolution in Computing... .- 6
|
||
A Paradigm. .....+-+++ee% 7
|
||
The'Shell:. 2 & &ssasers w @ & anaes oe KieKEHO A 6 w MEK @ gw exer we Oe eS Se 8
|
||
Shell Operators ©... eee ee ee et ee eee ee ee ee ee te 9
|
||
Compatibility with MS-DOS 9
|
||
Conclusions 2 «sieves io oo vreceveie eae eyeuere @ e easseg ew 6 SRS Oe Le 9
|
||
2. Relational Data Bases . ll
|
||
FileSooi.6 3 6 6 atin ll
|
||
COMMIS. 5 wren te ee Hotes ee EELS STF HT. S 12
|
||
ROWS 655 6 6 8 Eh aSH aD % BH Wistar, < HwIANA Sw oe EELS 12
|
||
Columns and Rows... 2-6 essences 13
|
||
Shell Programming and Flat ASCII Files ..... 13
|
||
Listes 6 6 Fo Gases & we eC ww SHEEN @ 14
|
||
REVIEW, can so a 8 sires ng me meee © 8 ewes 14
|
||
Normal Relations ..... 2... +e see ee eee eee 14
|
||
How Is Information Accessed? .......+++-5 ena DS
|
||
Selected /rdb Commands........... Paro at) vx o LS
|
||
Creating Tables and Entering Data ........ oe 17
|
||
REPOrts 6 5 eye nen en oe eerece eo eres av 1B
|
||
The Big Text Field Problem 19
|
||
Non-Text Data Structures...... a 2 7.20
|
||
Large Tables... 1-21 ee eee +. .20
|
||
Architectural Performance Enhancements . . .
|
||
SOE wieseiceie 9.0 oieicece fe 8 scene 8 eo roe Par
|
||
Fifth-Generation Systems .. 2... ee ce ee eee eee ee ee ee eee
|
||
References). cx acacese iw oo ¥) siete © © of qoene & © BmKereTe wm chee ee we esecere |e 8 EE
|
||
3. Commands,I/O, Pipes .......-.
|
||
compute: Compute a New Result. .
|
||
justify: Align Columns........-
|
||
|
||
total: Compute Arithmetic Totals. .
|
||
subtotal: Compute a Subtotal .. .
|
||
Quoting Commands ........-.
|
||
PHOS: 6s bo wo Sees ww Fae. a we Guar
|
||
|
||
Syntax: How To Enter Commands Correctly... 2.1 ee eee ee ee eee tees 32
|
||
|
||
==== PDF-Seite 4 ====
|
||
ii_ The COHERENT System
|
||
|
||
COHERENT Shell Scripts 2 sk sssarecn 6 6 sais wv % SOMERS © & Ba
|
||
Report Writing.........
|
||
Conclusion... ....6.0%
|
||
4. Entering Data into Tables . .
|
||
ver The: Forms: Rditor'vys'5 6 3 6 sie) 6 SF Mei BT G Retid 2 wo
|
||
|
||
enter: Mass Entry of Data.........
|
||
update: Updatea Table ....
|
||
Programs and Other Formats
|
||
Rules for Table and List File Set up . . .
|
||
Table Format .... 636 swe es
|
||
List Format .............
|
||
Tab Problems ............ eee
|
||
Seeing the: Tabs... os wiecsi9ve 2% eoeweneis © 6 MeeUNe wae 6
|
||
Table-Width Problems
|
||
Special Characters ies» «i pvsarsi ao, aware Hw ecaKenD WH Mi tH
|
||
Data Validation: How To Get Data Right
|
||
5. ve Form and Screen Editor
|
||
ve Commands...............
|
||
Moving Around............
|
||
Displaying Your Data
|
||
Getting the Right Row... . 2.6... eee eee ee eee
|
||
Inserting Text. sk wire so SF WWE FOE SRK TR He
|
||
Deleting TERE: wm gions oe ee SwtEWES & & Shai AH SENG & A EMM | 4 ERS
|
||
Targets 6. eee eee tee e eee eee eee eae
|
||
|
||
For Your Information
|
||
WEEN E ROWS: 5 6, esac. Se 6 PUT BD WSO FF Eels = » 0: exerayee © om eve
|
||
Getting Back to COHERENT
|
||
Quit Commands. .........
|
||
Colon Commands
|
||
MACKOS! 4 !95.5 3 5 THESES FF Filan wo o ee
|
||
|
||
FUCOpUONS <a ccm ta GHAR 6 HG. B Baas
|
||
|
||
Bile Creation. vcevesons 9 oo eueraus WW © HOIST & H Keele BS & ROIS
|
||
|
||
Using the Default File Names. ... 2.0... 0.0.0.0 00 cee uue
|
||
|
||
Automatic Row Numbering(-n)... 2.2... 0.0.0.0 eee eee
|
||
|
||
Start-up Mode Specification... 2... 0.0... 000 cue ee cues
|
||
|
||
Initialization Option
|
||
The Screen File: oo: csccswe oo & vers
|
||
|
||
Protecting Columns
|
||
Setting the Cursor
|
||
Phe Validation Pile! c6 v6 x. css 6 sh HPS FO E Raters
|
||
|
||
Validation File Creation. 2... 0... ee ee eee ee eee nae
|
||
Character Range Specification
|
||
Column Length Restrictions.
|
||
Look-Up Tables ...........
|
||
Table Creation.........
|
||
Decode Columns
|
||
Unique Columns
|
||
|
||
CONTENTS
|
||
|
||
==== PDF-Seite 5 ====
|
||
The COHERENT System iii
|
||
|
||
Column INnchasiONs; «ssi ee 6 acess 16 ww aiwIENd © Sw ATRL Le w HH wKMLRLE ew oe EEE 61
|
||
Multi-User Considerations. .. 6.6... eee eee tee eee eee eens 62
|
||
/rdb-ve Compatibility
|
||
|
||
Limits. .....-.4-
|
||
|
||
ve Validation. ....
|
||
|
||
Control-Key Mapping
|
||
Command-line Options
|
||
Screen Size and Column Limits . 2... ee ee ee ee ee eee eee 70
|
||
|
||
User Column in Audit Files... 26 6. ee ee ee eee 70
|
||
|
||
Fast-Access Indexing From ve . 6.6... eee ee ee ee ee ee eee 70
|
||
|
||
What Is the Cost of Indexed Searching?. .. 6.66 eee ee ee ee ee eee 70
|
||
|
||
6. Data-Base Design... 6 66. ee ee ee eee ee eee 73
|
||
One-to-One Relationships in One Table. 2... 6 6 ee ee ee ee ee ee 73
|
||
One-to-Many Relationships in Two Tables ...........--
|
||
Many-to-many Relationships in Three Tables .. 1.6. eee eee ee ee eee 74
|
||
Planning i csiciais 6 a 8 & sense is ew stares le we ebiewene © eo
|
||
Normalization 0:0 16 6 0 6) cceceneie oe senses ee 8
|
||
|
||
Functional Dependency .........++++
|
||
|
||
KeyS ss. ccsssiers 6 & & steven end % ¥ weuelare & & ®
|
||
|
||
Universal Relation .......+ ++ eee eee
|
||
|
||
Redundancy Problems. ..........++5
|
||
|
||
Update Problems .........-++e20+5
|
||
|
||
Insert and Delete Problems
|
||
|
||
First Normal Form .........-.
|
||
|
||
Second Normal Form.........
|
||
|
||
Third Normal Form.........-
|
||
|
||
Normalizing Example........-
|
||
|
||
Complex Queries with Joins .......
|
||
|
||
Pipeline Join... . 2. eee ee eee ene
|
||
|
||
tmpl
|
||
|
||
tmp2 ..
|
||
tmp3
|
||
|
||
Phone Book ....-+-++esee05%
|
||
|
||
7. Shell Programming. ... 1... ee ee eee ee eee
|
||
Data-Base Programming in COHERENT Shell Language... ... 6. +s eee ee ee eeee 87
|
||
COHERENT Utilities 4 ¢ & siscavars w ale aymcais we oi SiaaeS wow H EINREe a ww MANES HH slwie
|
||
|
||
awk: Language to Produce Complex Reports .
|
||
|
||
cat: Display a Table or List File
|
||
|
||
echo: RepeataStatement......
|
||
grep: Find All Rows That Contain a Given String ... 1-6 eee ee eee ee ees 88
|
||
od -c: Octal Dump All Bytes as Characters 88
|
||
|
||
sed: Stream Editor to Edit Fileina Pipe ...
|
||
sh: COHERENT Shell Programming Language
|
||
spell: Check Spelling in a Table or List File
|
||
|
||
tail: Display Bottom Rows of a Table or List File... 2... 6. ee ee ee ee eee 89
|
||
|
||
we: Word Count. 666i 6 oe ee biel eo 8 be ee oe ee ee ee wee ee ow eee 89
|
||
|
||
Text Editor to Enter and Update Files... 1... ee eee ee ee ee eee ee eee 89
|
||
|
||
Reading and Writing Data Base Files .. 6.61 eee ee te ee ee ee 90
|
||
Parsing ROWS 0.660 tet ee eee ee ee ee Hee eee ee ee Hee 91
|
||
Tables to Shell Variables... .. 2... 22-22 ee eee ee ee ee ee 91
|
||
Liste to Shell Variables: & Geciieis 6 easels FHT SH Ere Ae wae ww eH aNEK 93
|
||
Report Writing. 2... ee ee ee ee ee eee ee eee eee eee 94
|
||
|
||
8. Shell Menus . 2... cee ee ee eee ee eee eee meee eee ee ee 97
|
||
|
||
CONTENTS
|
||
|
||
==== PDF-Seite 6 ====
|
||
iv_The COHERENT System
|
||
|
||
Example Shell Menu Programs... oo srecece 9 9 eieiee © se ere we eR ee
|
||
CBS@ACHIONG & wxgcses a ow siereraie % H SETS SE
|
||
termput and tput Commands. ............
|
||
clear Commiandisjais 2s 5 BGs © OE PaNeals % HS
|
||
etirsor Commmianid:.... 2 6 « cieceere so saeras © & &
|
||
9. Tablesand Forms......
|
||
Building a Screen Form .
|
||
|
||
10. Fast-Access Methods. ..... 6... 0... eee eee eee
|
||
APPIOpelnte: Use si. 6 x sh 45S aes A SWISS Bd EL MOIS 4 HE MOTE W FE EME Me oe
|
||
The indexand search Commands. cceseice ce 6 0 eee © w & ware cd @ wo BNALENG wa % Bas
|
||
Searching oii 6 6 oasis & 6 FE HSS © FH Shetele o o eSessie oe eseree es ew me
|
||
IRTELACH VO hes a6 5 sarees mF BACAR Be WIG |S TAO 6 BG ROO GH OID ve
|
||
|
||
Pipe Key . 2... eee eee ee ee ees 0
|
||
File Inputiveis 6 & 2 isa 6 4 WG Sie SK © PAGO SS Gwe ews Ts: Fowlers ote 9 ove
|
||
File: Input by Pipes oe ois 6 ie «sca ee .
|
||
Multi-Rows, Multi-Columns, and Multi-Key:
|
||
Methods of Searching
|
||
Sequential... 2... . ee eee ee eee
|
||
Record vicscs eso scare as Hae’ we BG
|
||
|
||
Inverted or Indexed Sequential. ..............
|
||
Partial Inital Match
|
||
|
||
Analysis .........
|
||
Managements i 5 5.5 aileisies & & EWS 8 & Rlecene © om exe
|
||
11. Miscellaneous Commands. .................54.
|
||
Record Locking: One ata Time... . 2.2.2... ee eee
|
||
Finding What to Lock .....
|
||
lock and unlock. ........
|
||
Blankinga Record .......
|
||
Dates: Conversion and Arithmetic .
|
||
Julian and Gregorian... .. .
|
||
DiferenCe: x 6 wanais sa eo ees
|
||
Formats .. 1... eee eee eee eee
|
||
Conversions 6 60s 6 ob 6 ORK HE Tas
|
||
Set-TheoryCommands.............05.
|
||
Concatenating Tables ...........02000 ee
|
||
Subtract One Table From Another
|
||
Intersect Between Tables ...........000005
|
||
12. Combining /rdb with COHERENT. ..............
|
||
Multi-User Concurrent Access to Files ..........
|
||
|
||
BaGkUp.. - ooo seis % @ Serres
|
||
|
||
Checkpoint and Recovery
|
||
|
||
VAHGAYOR «6 a creas 6 6 & BHR 4 KH aTENS
|
||
|
||
AUG TYAS ANG LOCLIE so: en esnrcece 19 e SMROONS © & HORIALS te @ & TKEMENOND SFE WemNON | YF
|
||
13. Other Data-Base Systems................00.
|
||
|
||
RESOULCOUBE) onerere ie co 9 ercasioreie la ANOLE Me ew eREIEOIE
|
||
|
||
C Programming Unnecessary. ............0005
|
||
|
||
SPEEG:. x 5 a KMO @ SW RUeIOVENS wT SHRURE @ HO HaTGNSNS
|
||
|
||
Size
|
||
|
||
CONTENTS
|
||
|
||
==== PDF-Seite 7 ====
|
||
The COHERENT System _v
|
||
|
||
14. Can You Say that in English? . 0.0.66 ce eee ee eee eee ee ewe ne
|
||
Data-Base Models... .......++4-
|
||
|
||
Entity-Relationship..........
|
||
BIMMry <2 o prexenens 2 9 sieiee
|
||
Semantic Network ..........
|
||
Infological ......-++..+05-
|
||
PROLOG: Programming in Logic
|
||
The Grand Unified Field Theory of Information ..........
|
||
15. PROLOG and AL. 6 og ceceie 6 oo eeiene ee 0 eneene
|
||
PROLOG Language and Environment . .
|
||
Predicate Calculus
|
||
Facts ....5 e806
|
||
Questions
|
||
Rela w.. ee 2 saemeseune & & eieeeis
|
||
/rdb Interface to PROLOG. ........
|
||
tabletofact . . oicecoce es a6 speveses
|
||
tabletorule’. ¢ 5 osi)n 6 be ees
|
||
Problems of PROLOG. ..........++
|
||
searchtree: Data-Base Tree Searching. .
|
||
16. /rdband Co. wc e ce ees
|
||
Don't Do Nto:5 sc wsaravereyps we ierserve 6 & Hwreners
|
||
system(): Tell Shell to Execute a Program ......-..----
|
||
execl(): Execute a Call sccsie bb Seis 6 6 ein ea eee
|
||
execl() Shell Programs ..........+
|
||
fork(): Create a Child Process.
|
||
PIPES! s nyeeses woe w veers & TREES
|
||
One-Way Pipe.......+-+-+-++-
|
||
Pipe to Standard Input........
|
||
Two-Way Pipe .......+-++46-
|
||
Programming Style..........+..-
|
||
Fast Acceae! jc 2 oe vies © 0.8 HG © ©) HOKE we Chere
|
||
tabletostruct: Convert a Table toaC struct ..........4.-
|
||
Read Table into Memory: getfile() and fsize() ............
|
||
/rdb Functions: librdb.a.... . 6 6 ees ce eee nee nes
|
||
Colroutines: 6.1 ee ee Sie ees
|
||
Display Example ........--204-
|
||
Debugging... - 21. eee ee ee eee ee eens
|
||
Fast-Access Example
|
||
17. Manual Pages . 0... 1 eee eee eee eee renner ene
|
||
accounting termS . 6. 6 eee eee ee ee ee ee ee ee
|
||
List all /act commands .......
|
||
|
||
Addacolumn toatable........
|
||
|
||
Create adjusted trial balance table
|
||
|
||
Add a row to a table and update index tables .......... 172
|
||
|
||
Return the ASCII value ofa character... .....-.-.--- 174
|
||
RAN HTH SETNETHIE Ge MaNEENS @ CM METER A ORIENT Ww @ & NUS SHE MW SO SoM Ow & 176
|
||
|
||
Create balance sheet from adjusted trial balance ........ 176
|
||
|
||
Replace all data in a record with spaces. ............-- 177
|
||
|
||
Produce bill-of-materials from parts list............-- 178
|
||
|
||
Post payroll to ledgerpay... 1... eee eee eee eee 180
|
||
|
||
CONTENTS
|
||
|
||
==== PDF-Seite 8 ====
|
||
vi_The COHERENT System
|
||
|
||
calculate... ......0. Compute each tax form listed. ...........
|
||
CAD servis % & ERLE BS 8 Convert first letter of each word to upper case. .
|
||
SABHMOW 0 sw « siterexers & © Compute balance column of cash table........
|
||
chartdup.. . 6 6 6s i 8 6 Check for duplicate names and accounts in chart.
|
||
CReckrdb: cs snvcxe ws 3 Report any rows in which columns do not match head line . . 184
|
||
Chr... . eee ee eee eee Display the character corresponding to a number
|
||
ClearsrdDis 6 & ssieie's 6 8 Clear the terminal's screen .. 2... 2... eee ee eee
|
||
WSC irae a 0 & sxeneree a 6 Close accounting period creating journal for next
|
||
column..... display columns ofa table in anyorder..............
|
||
commands Describe /rdb commands... .......0. 000000 eee
|
||
compresss .. . - Squeeze out all leading and trailing blanks............
|
||
compute .... - Calculate columns ofatable ...............00005
|
||
computedate Add given number of days toadate............000-
|
||
consolidate. i ..06. 668s Combine all subsidiary journals to general journal... .... 195
|
||
Cpdirsrdb:. «cessor s & os Copy one directory tree to another directory .
|
||
catate. 6 bev e cee Produce customer statement ............. 000000
|
||
CUFBOR. 6k canes 6 6 2 8s Move the cursor to the row and column requested
|
||
CMS ME. ecsssysie ie on 6 suiniee a) ai» semanas Gee evanaa % ow alerts Bie Ey é
|
||
Gatatype & concis 6 6 8 86 Display the data type of each column selected .
|
||
Print a data-base dictionary. ...........0.000 eee
|
||
Blank record and update index file... ..........000%
|
||
Output table of rows that are in only one table ......... 205
|
||
Write table or list file to standard output. ............ 206
|
||
Display invalid values inacolumn..............0.05 207
|
||
OMber! 5 i SS So, gece Add rows to a table or list file without an editor......... 209
|
||
Oxplode ix sais 6 se Kavos Produce table of subparts and their count fora part. ..... 212
|
||
:(: ie Test for functional dependency of columns. ........... 214
|
||
filesize Return the number of characters ina file............. 215
|
||
fillform Fill a tax from with adjusted trial balancedata ......... 216
|
||
fixtotable Converts fixed length format to /rdb table format. ....... 216
|
||
fOOE 6: 5 ces Foot or subtotal Debits and Credit of ledger ........... 217
|
||
getjournal . Copy journals for sales, purchasing, pay systems. ....... 219
|
||
gregorian. .. Convert column of dates for arithmetic and format change .. 219
|
||
hashkey ... Return the hash offset for key strings. .....
|
||
head lineisia< % & 5 NGOS % yo: enessuere of e ciquecs WIE wreckaie h dierarausland tao suaeuacs
|
||
Head ecsie se & w acersrars Remove an /rdb head from both table and list files
|
||
headon...........- Add an /rdb header toatable .............04.
|
||
helpme esas 2 6 & g'siele es & List the help commands available ..............
|
||
howmany........... Display the number of commands in a directory... .. .
|
||
INdOK i555 eS NaN. Setup table for search. cee 6, severe ws eomarsvnrd
|
||
insertdash.......... Insert dash line as second line intable...........
|
||
intersect . 265i eee Write table of rows that are in both input tables...... .
|
||
MVOME as as Brees a 8 Print invoice fora sale order ...........00 0000s .
|
||
jointable . 2. ieee cas Join two tables into one where keys match............
|
||
jullaniss s 2 is eee ese Convert column of dates for arithmetic and format change . . 234
|
||
SUBHHEY oy. ce cee vicauenene - Left or right justify the columns ofatable ............
|
||
label... ... 204. - Print mailing labels from a mailinglist ....... .
|
||
Tengtlh. «x 6 &: sissavas - Return the length of its argument or input file
|
||
dk ee - Print form letters from a mailing list............
|
||
like ... : Find names that sound like anothername........
|
||
listtosh . Convert list format to shell variable............ rare
|
||
listtotable. Convert from list to table format... ...........0005
|
||
|
||
CONTENTS
|
||
|
||
==== PDF-Seite 9 ====
|
||
The COHERENT System _ vii
|
||
|
||
LOCK. i a &. siarerers wo 6 wos Lock a record or field ofa file... 6.6... . eee ee eee ee
|
||
lowercase. Transform text to lowercase ............4- ete
|
||
maximum Display the maximum value in acolumn..... .
|
||
|
||
mean... Display the meanofacolumn ............-
|
||
|
||
menu... Root menu with some COHERENT commands... . .
|
||
|
||
minimum. Display the minimum of each column selected .. . .
|
||
|
||
not..... Logical not, to reverse return status of command. . .
|
||
|
||
number Insert a column-row number into a table or list. . . .
|
||
|
||
Number Insert a column-row number into a table or list. . . .
|
||
|
||
pad .... Add extra spaces at end oflastcolumn.........
|
||
|
||
padstring. Return string with blanks to filla field .......
|
||
|
||
paste.rdb. Paste together two or more tables ..........
|
||
|
||
path.... Find the full path ofacommand...........
|
||
|
||
precision . Display the precision ofacolumn .......... seein
|
||
project .. Write selected projects (same as column). .........++.
|
||
prompt. . Echo a string on the standard output. .............-.
|
||
FAD.» ws List all /rdb programs in directory SRDB/bin . . .
|
||
|
||
record. . . Find and output a record froma table. .......
|
||
|
||
rename. . RENAMEACOMUNG§: 02054 © 8 cies sw HIKE ©
|
||
|
||
replace . . Insert a record into a file at specified location . . .
|
||
|
||
FEPOLls sc ovens wo & we Write reports using a form andatable .......
|
||
reportwriter......... Sample program to write standard reports .... .
|
||
|
||
rmblank: 5 sss. 6 5 se Remove blank rows fromatable...........
|
||
|
||
rmcore . . Remiove all Core fi1ES 0.0/5 5 « o) ceisiere a 0) 06 oceans oe of 8, eee
|
||
|
||
row .... Make a new table where rows match logical condition . .. . . 266
|
||
sale.... Enter sale order, and item, update customer. ..........
|
||
schema. . Print a table's schema ............-+255
|
||
|
||
screen. . . Convert a form into a screen-input shell program.
|
||
|
||
search. . . Search a table. « «.cevee = ¢ x ewes 2 HO waRw~ 2
|
||
|
||
searchtree Seek a string node in tree table... . 2.6... 6 ee ee ee eee
|
||
|
||
SOG: is ke oe ew Display nonprinting as well as printing characters
|
||
|
||
seek..... Return the beginning and ending offset of a row. .
|
||
|
||
select.... Output selected rows... 22 6 ee ei ress
|
||
|
||
SOTHABle 5 ica oe 6 aK8 Sort a table by one or more columns ........-..-0000%
|
||
SOUNKEK: § i665 FS FFs Convert a name into soundex code... ......--++0005
|
||
splittable . . Divide a table horizontally... ..........-..
|
||
|
||
substitute . Replace old string with new string. .........
|
||
|
||
subtotals 5 caowa ss ss Fe Output subtotals of columns inatable..............
|
||
NADICOFIBE, cece se wo eons Report whether a file has table or list format. ..........
|
||
tabletofact.......... Converts a table to PROLOG fact-file format . . .
|
||
tabletofix........... Convert /rdb table format to fixed-length format
|
||
|
||
FADIStOHAE,. 0 erence 2 ce 95 cnexe Convert a table to list format... .........-
|
||
|
||
tabletom4 .......... Convert a table to m4 define-file format... .. .
|
||
|
||
tabletorulle ...:0:5 60 6 see Convert a table to PROLOG rule-file format. . . .
|
||
|
||
tabletosed .......... Convert table format to sed file format ......
|
||
tabletostruct......... Convert table to C-language struct declaration .........
|
||
tabletothl ...0 oie eo ones Convert /rdb table format to UNIX tbl/nroff format. ...... 296
|
||
tax. «55 Compute tax from income and tax table ............. 296
|
||
termput. Get terminal capability from /etc/termcapfile.......... 297
|
||
testalls 6. is224 8 5 5 8 BER Test all /rdb programs in directory SRDB/demo ........ 299
|
||
testseareht crc 6 6 6 & czars Test the fast-access methods ........0 2.0.5 00 eeu ee 299
|
||
timesearch.......... Time fast-access methods... ....... 00005 eee eeee 299
|
||
todaysdate.......... Print today’s date in YYMMDD format............... 300
|
||
|
||
CONTENTS
|
||
|
||
==== PDF-Seite 10 ====
|
||
vili_ The COHERENT System
|
||
|
||
UNION. ws ee ese erees
|
||
uniondict. .
|
||
update.inv.... 0 sees
|
||
|
||
CONTENTS
|
||
|
||
Sum:accolumns & 8652,4 6 6 i608 6 Biecetes 2
|
||
|
||
Word-for-word substitution using a translation fille.......
|
||
|
||
Trim excess white space fromatable.......
|
||
|
||
Remove leading and trailing blanks from a string
|
||
|
||
Fetch termcap entry for a terminal type..... .
|
||
Concatenate tables... 2... ese eee eceee
|
||
|
||
. Combine three tables into translation dictionary
|
||
. Unlock a record or field ofafile...........
|
||
|
||
Multi-user update with screen form and record locking .. . .
|
||
|
||
Display and edit records in any sized file. ....
|
||
Convert input to all upper-case characters... .
|
||
Find invalid data... .seccecervenece
|
||
Visually editatable....... ee eee eee
|
||
Lock a table before editing, unlock afterward.
|
||
|
||
Create and display ve look-up tables .......
|
||
Display the command description and syntax . .
|
||
Display commands with functions in description
|
||
Output the width of the widest entries in a table
|
||
Display the width ofeachcolumn .........
|
||
|
||
. Convert text file into list of unique words. ... .
|
||
|
||
|
||
==== PDF-Seite 11 / Buchseite 1 ====
|
||
Section 1:
|
||
Introduction
|
||
|
||
/rdb is a relational data-base management system for COHERENT, MS-DOS. UNIX, and
|
||
other operating systems. It is designed to use the full power of the COHERENT shell and
|
||
supplemental tools, including awk, sed, and the C language.
|
||
|
||
With /rdb, you can implement a full-featured relational data base, including a menu-driven
|
||
data input and a report writer. Also, because large portions of /rdb are written in the shell
|
||
and related COHERENT tools, /rdb serves as an excellent tutorial in learning how to use
|
||
the full power of COHERENT.
|
||
|
||
Installing /rdb
|
||
|
||
To install /rdb, log in as the superuser root. Then cd to the directory in which you want
|
||
/rdb to live, say /usr. Then use the COHERENT command install to install the program.
|
||
install has the following syntax: install version device disks, where version is the version
|
||
number of the program being installed, device is the floppy-disk drive from which the
|
||
program will be installed, and disks is the number of disks that compose the installation.
|
||
|
||
The version number appears on your /rdb manual. The number of disks is one. If you are
|
||
installing from a high-density 5.25-inch floppy disk in drive O (drive A), device is
|
||
/dev/rhaO; if you are installing from a 3.5-inch floppy disk in drive 1 (drive B), then device
|
||
is /dev/fval. See the COHERENT Lexicon entry for floppy disks for a table of disk sizes
|
||
and devices.
|
||
|
||
For example, if you are installing version 2.0 from a 3,5-inch disk in drive 0, use the
|
||
command:
|
||
|
||
/etc/install 2.0 /dev/fva0 1
|
||
|
||
COHERENT will take care of the rest.
|
||
|
||
Be sure to edit your .profile to include the directory $RDB/bin. where SRDB is the
|
||
directory into which you installed /rdb. For example, if your .profile the PATH variable as
|
||
follows:
|
||
|
||
PATH=/usr/bin:/bin:$HOME/bin:.
|
||
|
||
and you have installed /rdb into directory /usr/rdb (which is the default), then you should
|
||
edit your PATH statement to read as follows:
|
||
|
||
PATH=/usr/bin: /bin:/usr/rdb/bin:$HOME/bin:.
|
||
|
||
European Keyboards
|
||
|
||
COHERENT version 3.2 lets you install any number of predefined keyboard definitions into
|
||
your keyboard driver. These let COHERENT support the keyboard layouts and national
|
||
character sets for most European countries.
|
||
|
||
If you are using /rdb with one of COHERENT's European-ized keyboard definitions, you
|
||
must rework three programs. These programs are the table editors ve and jve, and vindex,
|
||
ve's hash indexer. The European versions of these programs are located in directory
|
||
|
||
==== PDF-Seite 12 / Buchseite 2 ====
|
||
2 Introduction
|
||
|
||
SRDB/europe.
|
||
|
||
To use them in place of the default US keyboard versions, put the path $RDB/europe
|
||
before $RDB/bin in your PATH variable. For example, if /rdb’s home directory is
|
||
/usr/rdb, then insert the following entry into your .profile file:
|
||
|
||
export PATH=:/usr/rdb/europe:/usr/rdb/bin: "$PATH"
|
||
|
||
Or you can simply replace the US versions with the European ones:
|
||
|
||
ed /usr/rdb
|
||
mv ./europe/* ./bin
|
||
|
||
A side effect of the European versions of these programs is that characters that exceed the
|
||
decimal value of 127 are highlighted. In other words, characters such as umlauted and
|
||
accented vowels, tilded n’s. currency symbols, etc., will be highlighted in the screen displays
|
||
for ve, jve, and vindex. To suppress highlighting of eight-bit characters, make a new entry
|
||
in your /etc/termcap file by copying the entire description for your terminal type and
|
||
deleting the so (or standout) and us (or underscore) entries, up to and including the ':". For
|
||
example, the following copies the termcap entry ansipc, modifies it for European use, and
|
||
makes it into a new termcap entry called an-e. The portions in boldface are deleted:
|
||
|
||
ap-e|ansipc-eur|ansipc for european kbs: \
|
||
tal=\E[L:am:bs:bt=\E[Z:bw:cd=\E[0:ce=\E[K:ch=\E[$%i8d‘:cl=\E[20:\
|
||
rom=\E[%itd; $dH:co#80:cs=\E[%itd;tdr:cv=\E[%itdd:dl=\E[Msho=\E[H:\
|
||
:kO=\E[Ox:k1=\E[1x:k2=\E[2x:k3=\E[3x:k4=\E[4x:\
|
||
tk5=\E[(5x:k6=\E[6x:k7=\E[7x:k8=\E[ 8x:k9=\E[9x:\
|
||
tkb=*h:kd=\E[(B:kh=\E[(H:kl=\E[D:kr=\E[C:ku=\E[A:\
|
||
:1i#24:11l=\E[24;1H:hd=\E[C:se=\E[(m:sf=\E[S:sg#0:so=\E[7m:sr=\E[T: \
|
||
:te=\Ec:ue=\E[m:up=\E[A:us=\E[4m:\
|
||
+KI=\E (5x: KD=\E[3x:Kd=\E[P:KB=\E[6x:KU=\E[4x:Ku=\E[@:KM=\E[7x:KJ=\E[8x:\
|
||
:Kt=\E[Z:KT=\t:KL=\E[ 1x: KR=\E[2x:KP=\E[(U:Kp=\E[V:KX=\E[9x:KC=\E[0x:\
|
||
+KE=\E[24H:KW=*F :Kw=“R:Kr=“N:do=\E[B:
|
||
|
||
Once you have installed the new termcap entry, set your TERM variable in your .profile to
|
||
your new termcap entry:
|
||
|
||
export TERM=ap-e
|
||
|
||
Data Bases and COHERENT
|
||
|
||
There are two fundamental ideas that are necessary for application development in a
|
||
COHERENT environment. One is the relational model. which allows you to see all
|
||
applications as simple operations on tables. The other is the idea of using COHERENT tools
|
||
to pass data through pipelines and filter programs. instead of traditional programming.
|
||
|
||
Tables and COHERENT
|
||
|
||
First, we will introduce you to tables. All information can be entered into and manipulated
|
||
in tables. This is the fundamental idea of relational data bases. The COHERENT system
|
||
itself provides a rich and varied environment in which tables can be manipulated. After
|
||
covering basic operations, you'll see simple data-base design principles. Then you will learn
|
||
how to use COHERENT tools. You will also be introduced to advanced data-base problems
|
||
and solutions. There are a number of examples illustrating common data-base problems
|
||
and solutions, and a model business operation and accounting-system tutorial and manual
|
||
is included as a case study. Finally, all the manual pages are appended.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 13 / Buchseite 3 ====
|
||
Introduction 3
|
||
|
||
Operating Systems that Support COHERENT-Style Environments
|
||
|
||
By the COHERENT environment, we mean file redirection. pipes. and COHERENT-style
|
||
tools like awk, grep, and sed. This environment can be on a computer running COHERENT,
|
||
any of the various flavors of COHERENT, or MS-DOS with UNIX tools added.
|
||
|
||
Applications Development
|
||
|
||
When a person uses a computer in his work, he usually needs to have it programmed for
|
||
his particular application. A scientist might study the data from his experiment, an entry
|
||
clerk takes orders or reservations, a business person manges his business, an accountant
|
||
prepares financial statements and tax forms, a lawyer does research and prepare briefs, and
|
||
so forth. Some users can develop their own applications with COHERENT tools themselves.
|
||
But most users need to have computer professionals set up applications for them. In this
|
||
case, the power of the COHERENT environment eases the job of the developers and extends
|
||
what can be done.
|
||
|
||
Data Bases
|
||
|
||
Almost all applications require some form of data base. Typically, a data-base management
|
||
system is a computer program that maintains data and performs tasks such as easing the
|
||
input and validation of data, finding data, computation and transformation of data,
|
||
reporting, and so forth.
|
||
|
||
COHERENT Environment
|
||
|
||
The COHERENT system is not just an operating system. It has hundreds of programs that
|
||
work together to do most of the common computer jobs. COHERENT tools provide an entire
|
||
support environment for software application development and operation. It does so much
|
||
of the work, that the jobs of both the developer and the user are enormously simplified. But
|
||
since this environment is new to the computer profession, it is seldom used to its maximum
|
||
potential. Often, developers don't know how to do on the COHERENT system many of the
|
||
things they are used to doing on other systems. Frequently, developers do things in the
|
||
COHERENT environment in difficult or slow ways that could be done much better if they
|
||
knew how.
|
||
|
||
Many data base systems are now available on the market. But almost all are software
|
||
prisons that you must get into and leave the power of COHERENT behind. Most were
|
||
developed on operating systems other than UNIX or COHERENT. Consequently, their
|
||
developers had very few software features to build upon, and wrote the functionality they
|
||
needed directly, without regard for the features provided by the operating system. The
|
||
resulting data base systems are large, complex programs that degrade total system
|
||
performance, especially when they are run in a multi-user environment.
|
||
|
||
COHERENT provides hundreds of programs that can be piped together to easily perform
|
||
almost any function imaginable. Nothing comes close to providing the functions that come
|
||
standard with COHERENT. Programs and philosophies carried over from other systems put
|
||
walls between the user and COHERENT, and the power of COHERENT is thrown away.
|
||
|
||
The shell, extended with a few relational operators, is the fourth-generation language most
|
||
appropriate to the COHERENT environment.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 14 / Buchseite 4 ====
|
||
4
|
||
|
||
Introduction
|
||
|
||
Fourth Generation Systems
|
||
|
||
In recent years, a variety of developments in programming language design have emerged.
|
||
Object-oriented languages are becoming common, and languages explicitly supporting
|
||
multiple tasks and inter-task communication are also gaining popularity. Unfortunately,
|
||
these efforts have resulted in productivity increases too small to offset the growth in the size
|
||
and complexity of software systems. A response to this has been the development of fourth-
|
||
generation programming languages. Although not commonly thought of as such, the
|
||
COHERENT shell is one of the most powerful and flexible fourth-generation languages
|
||
available.
|
||
|
||
Attempts at a Definition
|
||
|
||
There is no consensus on the definition of what constitutes a third- or fourth-generation
|
||
language. Mainstream third-generation languages are typed, procedural languages. They
|
||
are standardized and largely hardware independent. Operations in the language must be
|
||
specified in a detailed. step-by-step algorithmic fashion. Third-generation languages do very
|
||
little implicit processing. Third-generation languages are general purpose, even most of
|
||
those that were ostensibly designed as special purpose languages.
|
||
|
||
Fourth-generation languages are usually intended as design tools for a particular
|
||
application domains. They are usually free form in their use of variables, often not
|
||
requiring type definitions and allowing dynamic typing of variables. They don't emphasize a
|
||
modular, procedure-based style of coding. Instead, they contain a number of predefined
|
||
procedures for performing various high-level operations. The high-level operations involve
|
||
large amounts of implied processing. For example, a “sort” operator is usually available.
|
||
The facilities of a fourth-generation language are usually both more powerful and less
|
||
flexible than the facilities available in a third-generation language.
|
||
|
||
A fourth-generation programming language (4GL) should let you simply write what it is you
|
||
want, rather than a detailed procedure of how to produce it. Although many products call
|
||
themselves 4GLs today, they are mostly rewrites of COBOL and report writers. They are too
|
||
low level and tedious. This is definitely not what a 4GL should be.
|
||
|
||
Previous Generations
|
||
|
||
The first generation of computer languages was the sequence of zeroes and ones that were
|
||
the machine instructions. In the beginning people had to code in this way.
|
||
|
||
The second generation was “assembly language,” which has a one-to-one correspondence
|
||
with machine instructions. For example, this assembly-language code adds register 1 to
|
||
register 2:
|
||
|
||
add rl,r2
|
||
|
||
One line of code produced one computer instruction. Then, in about 1956, FORTRAN was
|
||
written to do formula translation, and it became much easier to write programs. Each line
|
||
of code produced several computer instructions. The third generation has come to
|
||
encompass sophisticated macro assembly languages, and other so-called high-level
|
||
languages like C, COBOL, Pascal, LISP, PL/1, and many others. There are advanced
|
||
constructs close to English like if, then, and else, but the types of statements are
|
||
constrained to mostly arithmetical operations, with limited string capabilities. A typical
|
||
third generation program consists of statements like:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 15 / Buchseite 5 ====
|
||
Introduction 5
|
||
|
||
for i=1 to 10
|
||
print i, sqrt(i)
|
||
next i
|
||
|
||
The next step comes in describing what you want and letting the computer figure how to
|
||
give it to you. The fourth-generation has English-like words, but statements typically deal
|
||
with more than numbers, and are “non-procedural.” A fourth-generation environment, for
|
||
example, reduces a program to sort all the lines in a file to:
|
||
|
||
sort file
|
||
|
||
Fourth-generation language primitives often include relational operators, while third-
|
||
generation languages generally do not. And, when you need to mix procedural with non-
|
||
procedural instructions, that is easy to do. For example:
|
||
|
||
for file in filel file2 file3
|
||
do
|
||
|
||
sort $file
|
||
done
|
||
|
||
At the COHERENT shell level, you can in many cases say what you want without saying
|
||
how (non-procedural), and you will get it. For example, type the command
|
||
|
||
sort file
|
||
in the the COHERENT shell and you get a sorted file. Or, type
|
||
spell file
|
||
|
||
and you get a list of words in your file that are not in the dictionary. One line of commands
|
||
calls one or more programs, each of which may have thousands of instructions.
|
||
|
||
With the shell, you can put together an application in minutes or hours, instead of the
|
||
weeks or months required with 3GL code. In a 4GL, you should be able to write most
|
||
applications in a line or two. With the shell, you can say things like:
|
||
|
||
column Account Amount Description < file |
|
||
grep expenses |
|
||
|
||
sort |
|
||
|
||
lpr
|
||
|
||
This short program extracts some of the columns in a file, pipes them through another
|
||
program to select the rows that contain the string expenses, sorts the selected strings, and
|
||
prints them.
|
||
|
||
This same report would take tens to hundreds of lines in COBOL, PL/I, C, and most
|
||
commercial 4GLs. In those languages. you write instructions one at a time, to process
|
||
records from the file one at a time. This is very tedious compared to writing one instruction
|
||
to operate on the entire file.
|
||
|
||
Data Structures in the Data
|
||
|
||
In an ideal environment, the structure of data is in the data. Newline-separators for records
|
||
and column-separators for fields can tell any program where the fields and records are.
|
||
3GL languages must have the data structure hard-coded into them, so that a program can
|
||
read only one kind of file.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 16 / Buchseite 6 ====
|
||
Introduction
|
||
|
||
In a traditional third-generation environment, the structure of the file must be hard coded
|
||
into the program. In a fourth-generation environment, files have their structure embedded
|
||
with newline and tab record and field separators. Any program can find a record by just
|
||
looking at the stream of characters. Add a single character to the data file read by a COBOL
|
||
program and all is changed or lost, so you must do file conversions in the COBOL
|
||
environment all of the time. And these are done in COBOL. Any changes require that you
|
||
edit and recompile all of the programs that read that file.
|
||
|
||
In addition, there are no file operators in 3GLs, only field-at-a-time instructions. Therefore.
|
||
you must write loops to process each record. This takes much more code than just
|
||
processing a whole file at a time.
|
||
|
||
Most commercial 4GLs are very similar to COBOL. You still have to do record-at-a-time
|
||
processing. If the COBOL program takes 100 lines, the 4GL will take anywhere from 50 to
|
||
100 lines, to do what we did above in one pipeline.
|
||
|
||
A Revolution in Computing
|
||
|
||
If you write C programs on COHERENT, you miss most of the advantages of shell-level
|
||
programming. It's been suggested that since C and other languages on COHERENT give
|
||
you the system() function call, this converts them into 4GLs. This is equivalent to saying
|
||
that assembler is a 4GL if it has a system() function. But on non-COHERENT operating
|
||
systems like MS-DOS and VMS, there is not as rich a variety of tools available as in
|
||
COHERENT, except to the extent that COHERENT has influenced these systems.
|
||
|
||
The COHERENT system itself offers an integral tree index approach to data organization:
|
||
the hierarchical file system itself. Many utilities traverse these trees, search them, add and
|
||
delete nodes, and in general provide procedural tools with which to deal with files. The
|
||
same is true of MS-DOS and Macintosh systems. The opportunity is afforded to avoid re-
|
||
inventing the wheel.
|
||
|
||
This really is a revolution in computing. Working with great tools will spoil you, but most of
|
||
the computing world is still writing COBOL. To have to go back and forth between such
|
||
environments is painful.
|
||
|
||
A good 4GL should be written in C — once. It should be written to be so general in purpose
|
||
and so easy to use that its functionality can be used from then on, rather than recoded in
|
||
each application. Then these good programs can be used to put together applications, not
|
||
coding each entire application in C, unless there is some critical need.
|
||
|
||
As you become more familiar with their environment, you will become more able to use the
|
||
power of these advanced systems. if only to shorten repetitive command sequences —
|
||
another key feature of 4GLs. Every computing environment has facilities to collapse a
|
||
sequence of keystrokes; these include aliasing, scripting, and macro construction.
|
||
|
||
Marketing people got wind of 4GL and turned it into a big marketing hype. Most data base
|
||
management systems wrote their own procedural language like COBOL or RPG and called it
|
||
a4GL. They are usually worse than COBOL, because you have to learn their new language.
|
||
rather than use a classic. Few 4GL designers put as much time and energy into designing
|
||
their language as was put into COBOL.
|
||
|
||
The driving force behind fourth-generation languages comes from several needs.
|
||
Programming projects commonly involve man-years of work. The shortage of experienced
|
||
software engineers and the need to increase productivity pushes us towards tools allowing
|
||
faster development cycles. The increased use of computers by users who do not have formal
|
||
computer science education requires very high-level tools that let novice programmers
|
||
concentrate on algorithms rather then implementation details. As more work is done on
|
||
computers, there is more demand for single-use programs to perform a specific task. The
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 17 / Buchseite 7 ====
|
||
Introduction 7
|
||
|
||
relatively high expense of coding a software tool with a one time use encourages the use of
|
||
any method available for simplifying the development process.
|
||
|
||
As third-generation languages are becoming increasingly less able to meet the diverse needs
|
||
of computer users, several principles of software design are gaining great popularity.
|
||
especially within the UNIX/COHERENT community:
|
||
|
||
. Data should be kept in flat ASCII files, not binary, so that we can always see what we
|
||
are doing, and do not have to depend upon some special program to decode our data
|
||
for us.
|
||
|
||
* Programming should be done in fourth-generation languages, except when the
|
||
expected heavy use and/or resource consumption of the program justify the expense of
|
||
a more efficient coding in a third generation language.
|
||
|
||
: Programs should be small and should pass data on to other programs. Software
|
||
prisons, or large programs with self-contained environments, must be avoided because
|
||
they require learning and they make extracting data difficult.
|
||
|
||
° We should build software and systems to meet interface standards so we can share
|
||
software and stop dreaming that any individual or company can do it all from scratch.
|
||
|
||
Approaching software engineering with principles like these does have some drawbacks.
|
||
The major drawback is that fourth-generation languages almost always produce slower code
|
||
then third generation languages do. As computers increase in speed and power, this
|
||
drawback becomes less of a consideration. As improved compiler optimization techniques
|
||
spread, the difference between code produced by 3GLs and 4GLs will become smaller.
|
||
|
||
A Paradigm
|
||
|
||
A programming paradigm is important for ensuring that a language is robust and has a
|
||
consistent style to its syntax and semantics. Paradigms for fourth-generation languages
|
||
must meet requirements more stringent than those for third-generation languages. To
|
||
start, a fourth-generation language should provide a consistent interface to high-level
|
||
facilities working with a variety of complex data types, while simultaneously providing
|
||
fundamental low-level language constructs for coding any functionality missing from the
|
||
predefined facilities. Too many 4GL’s are good only for projects within a narrow application
|
||
area. It's difficult to allow for high-level constructs from a variety of fields without the
|
||
programmer having to specify the level of detail required in a 3GL.
|
||
|
||
The paradigm we choose for fourth-generation languages is the operator/stream paradigm.
|
||
In this model, data flows in unidirectional “streams” on which operators are placed. Each
|
||
operator transforms the data as it passes by. The set of streams in a program form a
|
||
directed graph, possibly with cycles. This paradigm concentrates on what needs to be done
|
||
to the data, and deemphasizes the techniques used in the transformation.
|
||
|
||
Fourth-generation languages that attempt to use only the procedural paradigm of
|
||
mainstream third-generation languages usually end up being limited to a_ specific
|
||
application domain. The procedural model doesn't describe data in an abstract enough
|
||
way. Different types of operations require too much detailed code to work with. and the
|
||
languages do not have the simple relation between all data and operators the way an
|
||
operator/stream paradigm does.
|
||
|
||
A side benefit of using the operator/stream paradigm appears in the design of graphical
|
||
programming tools. Traditional third-generation languages haven't been well adapted to a
|
||
graphical programming interface. The problem stems, in part, from the difficulty of
|
||
expressing the numerous possibilities in an intuitive pictorial way. With operator/stream
|
||
as the basis for a language, a graphical programming aid can easily convey the process of
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 18 / Buchseite 8 ====
|
||
Introduction
|
||
|
||
placing an operator on a stream.
|
||
|
||
The operator/stream paradigm has proven effective in more domains than just language
|
||
design. Some UNIX kernels make use of the paradigm to reduce the complexity of the
|
||
operating-system code. Rather than having one large, complex piece of code handling all
|
||
the functionality of a particular aspect of the operating system (such as a device driver),
|
||
data in the kernel is run through a linked set of operators, each operator performing one
|
||
small, well-defined function. This lets users modify the system by introducing new
|
||
operators, without having to understand the innards of other operators on the stream.
|
||
|
||
The Shell
|
||
|
||
The shell and the set of COHERENT utilities form a fourth-generation language based on
|
||
the operator/stream paradigm. The critical feature of the shell that puts it in the class of
|
||
4GL's is the COHERENT pipe, which allows a shell to start a sequence of processes, each
|
||
reading its input from its predecessor process and writing its output to a successor process.
|
||
The pipe is one of the major reasons leading to the adoption of UNIX and its offspring.
|
||
including COHERENT, as the standard multi-user operating system. Unfortunately. few
|
||
people fully understand the philosophy behind it; most software developers are still
|
||
producing large, self-contained applications using data formats incompatible with anything
|
||
else.
|
||
|
||
For the shell, the COHERENT pipe provides the data streams, and the hundreds of standard
|
||
COHERENT utilities provide the core set of operators. The power of this approach is
|
||
tremendous. Because the data streams are flat ASCII, all the operators can read each
|
||
other's data. COHERENT includes a few standard utilities that can perform most of the
|
||
data formatting needed to transform one program's output to the form required by another.
|
||
In addition, using stand-alone programs as operators allows easy use of custom or
|
||
commercial packages of operators, such as statistics or data base packages. This
|
||
modularity encourages code reuse, and the flat ASCII stream format makes it easy to get
|
||
operators from a variety of sources talking to each other. Finally, because the operators can
|
||
only transform the data stream running through them, side effects can’t surprise the
|
||
software engineer by giving unexpected results,
|
||
|
||
The COHERENT file system also provides a hierarchal storage medium for data. Because
|
||
COHERENT files are flat ASCII data files, and COHERENT deliberately attempts to make all
|
||
data sources look the same, most utilities can't distinguish between data coming from a
|
||
stream and data coming from a file. This gives great flexibility, allowing the shell to store
|
||
the results of a pipeline into a file, and then feed that data back into a stream at some
|
||
future point.
|
||
|
||
There are two frequent criticisms of fourth-generation languages. It is often noted that
|
||
4GL's tend to be suited for a particular application area, and that their low-level facilities
|
||
are not up to the task of providing complex functions that don't already exist in the high-
|
||
level library. The shell escapes this problem: COHERENT utilities can be written in any
|
||
language, from shell scripts to assembly language. If a tool is needed which isn't currently
|
||
available, the developer is free to pick the language most suited to solving the problem,
|
||
whether it’s a CASE tool or standard C. This ability to combine the shell with products of
|
||
all other existing development tools results in a uniquely general 4GL.
|
||
|
||
Many also complain that fourth-generation languages sacrifice too much efficiency for the
|
||
sake of short source code and high-speed development, The ability to use operators from
|
||
any source is an answer to this complaint as well. It allows a shell programmer to code
|
||
speed-critical routines in a language more suited to efficiency considerations. If an
|
||
application requires floating-point number crunching, one codes the appropriate routines in
|
||
FORTRAN and the non—time-critical sections of the code can still be done in the high-level
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 19 / Buchseite 9 ====
|
||
Introduction 9
|
||
|
||
shell code.
|
||
|
||
With the shell, development is quite easy for even the novice programmer. The interpreted
|
||
environment allows easy access to the internals of the script as it runs, as well as a fast
|
||
test-change-test cycle. The flat ASCII data format and lack of operator side-effects make it
|
||
easy to examine the effect different operators have on the stream of data.
|
||
|
||
Shell Operators
|
||
|
||
The shell relies heavily on its operators. For example, it has no built-in ability to evaluate
|
||
expressions; instead, it uses the test utility to to that.
|
||
|
||
The “string” data type is the only one the shell supports. The shell assumes that there are
|
||
operators which will do any more advanced data type a programmer might need. Operators
|
||
exist to perform numerical functions. For multi-field records. operators commonly use the
|
||
space or tab character as a field separator and the newline character as a record terminator.
|
||
This allows great flexibility, despite the overhead incurred of converting data into and out of
|
||
ASCIl for non-string operations.
|
||
|
||
One of the greatest strengths of the shell is the ability to process an entire file with a single
|
||
command. The shell does allow for defining procedures, as well as execution control
|
||
constructs like if, while, and case. However, these flow-control constructs are often not
|
||
needed. For example, the script presented in the following section explicitly performs no
|
||
looping, because the operators implicitly loop, acting on each line of the program.
|
||
|
||
Compatibility with MS-DOS
|
||
|
||
MS-DOS shares key underlying features with COHERENT, enough so that the
|
||
operator/stream paradigm can be utilized identically in both environments. Except for
|
||
minor limitations on file name syntax, the MS-DOS hierarchically structured file system
|
||
appears to the user to be functionally identical to the COHERENT file system. The multi-
|
||
tasking capabilities of COHERENT, while missing from DOS, are not essential elements of
|
||
the paradigm. Although DOS shells use intermediate temporary files to implement pipes.
|
||
the interface presented to users, even using command.com, can be described with the
|
||
operator/stream terminology we use here. The COHERENT shell and awk are available as
|
||
MS-DOS shell replacements and enhancements.
|
||
|
||
Conclusion
|
||
|
||
The shell is quite a powerful tool indeed. It is not without limitations, however. First, only
|
||
a few companies are currently producing tools oriented towards use in shell scripts. /rdb
|
||
remedies the shell's weakness of not being able to store complex data types, and there are
|
||
many additional tools for for correcting some of the other major limitations, such as
|
||
numerical computation, statistical analysis, and business graphics output. Although
|
||
COHERENT has applications dedicated to mathematics and numerical analysis, most are
|
||
themselves large self-contained programs. A programmer who needed matrix inversions, for
|
||
example, must adapt existing tools, like System S or SAS, to work within shell scripts, or
|
||
write a special purpose tool.
|
||
|
||
The shell needs improvement in the ability to connect multiple pipes together more freely.
|
||
The original designers didn’t anticipate the need for more than linear pipelines. Although
|
||
more complex, non-linear pipes can be created by the use of temporary files, this method is
|
||
only barely adequate for constructing complex structures such as cyclic streams. Finally.
|
||
more operators are needed that allow incoming data to be split between or duplicated on
|
||
multiple output pipes.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 20 / Buchseite 10 ====
|
||
10 Introduction
|
||
|
||
The shell shares another problem with weakly typed languages: errors in the format of that
|
||
data stream can lead to unexpected output. Because no method of type- or format-checking
|
||
is built into the shell, the programmer must write code that avoids the problem. The
|
||
interpreted environment does allow careful examination of the stream data as it passes
|
||
through each operator, which reduces the difficulty of writing error free code. The shell
|
||
won't lend itself to the sort of correctness proofs offered by the newer CASE tools unless a
|
||
formal definition is proffered, specifying not only syntax but all the operators as well.
|
||
|
||
The operator/stream paradigm has produced a simple, powerful, general purpose tool. It
|
||
allows one to prototype or generate a proof of concept in hours or days. when it might have
|
||
required weeks with C. Although the shell produces slower code than a third-generation
|
||
language, the increasing power of modern computers makes this a minor concern for many
|
||
tasks. This framework provides an easily visualizable way of manipulating large (or small)
|
||
amounts of structured data.
|
||
|
||
Although there is currently a shortage of utilities designed for general-purpose use within
|
||
shell scripts, awareness of the potential of shell programming is spreading, and more
|
||
packages are being written outside of the traditional monolithic program tradition. In this
|
||
way, computing is coming full circle, returning to the original concepts of Von Neumann,
|
||
whose computing paradigm embodies the stream of sequential memory passing by the
|
||
operator of the central processing unit.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 21 / Buchseite 11 ====
|
||
Section 2:
|
||
|
||
Relational Data Bases
|
||
|
||
Files
|
||
|
||
The central idea of relational data bases is that all information can be put into tables and
|
||
can be manipulated by a few simple operations. This is a revolutionary idea and takes some
|
||
thinking to understand. It means that all of our information needs can be handled in a
|
||
simple way. All information, data. knowledge. facts. or whatever you call it. can be put into
|
||
tables. For example, a table named expenses might look like this:
|
||
|
||
Date Amount Account Description
|
||
850125 67.00 4120 plane ticket
|
||
850126 12.00 4120 meal with client
|
||
850127 150.00 4120 hotel bill
|
||
|
||
At the top of the table are the column names. The dashed line makes it easier to read, and
|
||
separates the header from the data rows. Each row of the table holds information about a
|
||
particular expense item.
|
||
|
||
We see information in tables every day — train schedules, scientific data, phone books,
|
||
restaurant menus, price lists, catalogs, math tables, conversion tables, accounting and
|
||
financial reports, tax forms, and so on. We all understand tables: we know how to fill them
|
||
in and how to look up information in them. Tables and our operations on tables are
|
||
independent of the information they contain. The purpose of this book is to help you to
|
||
think about your information problems in terms of tables and operations on tables.
|
||
|
||
In accounting, information is collected in journals, then manipulated to create financial
|
||
statements that you can review to see the state of the business. Scientists have
|
||
instruments in their labs that collect data and store it in their computers. Statistical
|
||
programs compress masses of data into simple tables and graphs for the scientist to look at
|
||
to see responses of systems to various inputs and to discover causal relationships.
|
||
Employee information is stored in tables and can be extracted to print pay checks, make
|
||
phone books, and so on.
|
||
|
||
When we take these abstract ideas to the COHERENT system, we find a friendly
|
||
environment for storing tables and manipulating them. Computers store tables in files that
|
||
live on hard disks. They have names by which they can be called up. Tables can be created
|
||
with a text editor, with COHERENT commands, from other tables, or imported from other
|
||
COHERENT data base systems, or even foreign systems. Once tables are implemented as
|
||
ordinary COHERENT files, there is available a plethora of COHERENT utilities for
|
||
maintaining security, data integrity. and ancillary information about tables.
|
||
|
||
There are only three rules for creating a table in the COHERENT and /rdb environment:
|
||
° A tab is inserted between each column.
|
||
* On the first line of the table, each column is given a name.
|
||
|
||
11
|
||
|
||
==== PDF-Seite 22 / Buchseite 12 ====
|
||
12 Relational Data Bases
|
||
|
||
* The second line of the table has lines of dashes for each column, showing the width of
|
||
the column.
|
||
|
||
This is much easier for the user than systems that require the overhead of setting up
|
||
schema and special files. Once tables are created, they can be manipulated by COHERENT
|
||
and /rdb. Using the ve forms editor to initially create tables and enter data from your
|
||
terminal avoids potential problems caused by (among other things) the wrong number of
|
||
tabs.
|
||
|
||
Columns
|
||
|
||
Rows
|
||
|
||
When we try to look up information in a table, we usually find that there is a lot more
|
||
information there than we want. We have to find the single fact we want from all the rest.
|
||
Often. there are more columns than we need. Therefore, we want to reduce the table to only
|
||
those columns we need. When we look at a table with our eyes, we try to ignore the extra
|
||
columns. Or we use our fingers to scan down the column we want.
|
||
|
||
When using the computer we have a command called column, which is a program that
|
||
inputs one table and outputs another table that has only the columns you specify. For
|
||
example consider our expenses table. One can project some of the columns of a table by
|
||
typing this simple command, which says to project columns Amount and Description from
|
||
the input expenses table:
|
||
|
||
column Amount
|
||
This produces:
|
||
Amount Description
|
||
|
||
67.00 plane ticket
|
||
12.00 meal with client
|
||
150.00 hotel bill
|
||
|
||
Note that now we have a new, smaller table with only the two columns we want to see. For
|
||
another example, you might project just the names and phone numbers from the employee
|
||
table to make a phone book. In other words, the company phone book is a projection of the
|
||
name and phone columns of the employee table.
|
||
|
||
The most common operation is to search the table for a specific piece of information. We
|
||
want to know when the next plane leaves, the price of the scallops on the menu, the degrees
|
||
Centigrade for 72° Fahrenheit, the ball player with the highest batting average, the grade for
|
||
a class on a report card, the amount spent on phone calls by the company last year, and so
|
||
on. Each search requires that we select just one, or a few, rows from a table.
|
||
|
||
On the computer, you can select only the rows desired with the row command. Here we
|
||
select all rows in the expenses table in which Amount is greater than 50:
|
||
|
||
row ‘Amount > 50’ < expenses
|
||
|
||
This produces:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 23 / Buchseite 13 ====
|
||
Relational Data Bases 13
|
||
|
||
Date Amount Account Description
|
||
850125 67.00 4120 plane ticket
|
||
850127 150.00 4120 hotel bill
|
||
|
||
With one simple operation you can select information from any table containing any data.
|
||
|
||
Columns and Rows
|
||
|
||
Often you want to find one or a few rows and see only a few columns. On COHERENT you
|
||
can put these two commands together. The COHERENT pipe symbol ‘|’ means to take the
|
||
table that is output from the column command on the left and input it into the row
|
||
command on the right:
|
||
|
||
column Amount Description < expenses | row ‘Amount > 50’
|
||
|
||
This produces:
|
||
Amount Description
|
||
|
||
67.00 plane ticket
|
||
150.00 hotel bill
|
||
|
||
Since the output of one program can be piped into the input of another, you can create
|
||
report programs with one or a few lines of commands and pipes. For example, you can
|
||
project some columns of a table with the column command, pipe the output to a row
|
||
program which will select certain rows, pipe that output to a sorttable program which sorts
|
||
it, then on to a jointable to pick up other columns from another table. All of this can be
|
||
done by typing one line on your terminal. Or this line can be typed into a shell program file
|
||
with a text editor, and given a name, like weeklyreport. Then, by simply typing
|
||
weeklyreport, the report can be produced when you wish. Several reports can be invoked
|
||
by a higher level shell script. This is called shell programming.
|
||
|
||
These reports, and other programs, can be placed in a menu and selected with a few
|
||
keystrokes, or if you have a terminal with a mouse, by pointing and clicking. Therefore, you
|
||
can automate whole operations in hours and days, rather than the months and years that it
|
||
takes on other systems.
|
||
|
||
Shell Programming and Flat ASCII Files
|
||
|
||
The key to this approach is shell programming and flat ASCII files. Flat means there is no
|
||
structure to them. COHERENT thinks of them as a stream of characters. ASCII is a
|
||
standard code for converting characters to numbers for storage in the computer. The files
|
||
have variable length records and fields. This is a break from the IBM tradition of structured
|
||
binary files with fixed length records and fields. Breaking with this old tradition is an
|
||
essential part of the COHERENT revolution.
|
||
|
||
This does not mean that /rdb cannot manipulate binary data. We will discuss
|
||
manipulating arbitrary binary objects later.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 24 / Buchseite 14 ====
|
||
14 Relational Data Bases
|
||
|
||
Lists
|
||
|
||
In addition to the table format shown previously, /rdb also has a list format for data that is
|
||
hard to fit into a table, such as mailing lists. For example:
|
||
|
||
Number 1
|
||
|
||
Name Rambo
|
||
|
||
Company One Man Army
|
||
Street 123 Mac Attack
|
||
City Anywhere
|
||
|
||
State Thirdworld
|
||
|
||
ZIP 30000
|
||
|
||
Phone (111) 222-3333
|
||
|
||
Number 2
|
||
Name Chuck
|
||
Company eee
|
||
|
||
Note that the list format begins with a blank line, unlike the table format, and that a single
|
||
tab separates the field name from the data for each field. You can use the COHERENT vi
|
||
text editor or /rdb's ve form editor to initially create tables, and to enter and edit data ina
|
||
table. You can convert from table to list and from list to table format easily with the
|
||
tabletolist and listtotable commands.
|
||
|
||
Review
|
||
|
||
A relational data base is a collection of relations or tables that may be related on one or
|
||
more common columns. Relational data bases implemented like this are easily
|
||
transportable from one environment to another.
|
||
|
||
Relational data bases have a solid mathematical base in relational set theory, relational
|
||
algebra, and relational calculus. There are theorems in this relational math that prove that
|
||
any data put into a relational data base can be extracted. The mathematical base also
|
||
assures that manipulations performed will have correct results, just as arithmetic assures
|
||
us that the math functions we perform on the computer have correct results.
|
||
|
||
Normal Relations
|
||
|
||
An /rdb relation, or table, is an ordinary ASCII file. An /rdb table has rows, or records,
|
||
separated by newlines. It has fields, or columns, separated by a tab character. Every row
|
||
must have the same number of columns. This is first-degree normalization.
|
||
|
||
The first row of a table contains the names of the columns; the second row contains
|
||
columns of dashes. Any kind of information can be represented in such a table: numbers,
|
||
words, file names, etc: /rdb commands and relational set theory doesn’t care about the
|
||
content of the table — just as long as these rules are followed for the form of tables.
|
||
Another important rule to remember when designing a data base is:
|
||
|
||
If many columns are used in a single row to describe the same type of information, it's time
|
||
to make a new table.
|
||
|
||
For example, consider a table of family members:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 25 / Buchseite 15 ====
|
||
Relational Data Bases 15
|
||
|
||
id mom dad kidl kid2
|
||
a: mary jack billy bobby
|
||
2 nancy joe terry susie
|
||
3 sally john adam
|
||
|
||
In this example there are two kid columns in each row. The right way to express this
|
||
relationship is with two tables: one for parents and one for kids. They are related or linked
|
||
by a common column, id.
|
||
|
||
id mom dad
|
||
1 mary jack
|
||
2 nancy joe
|
||
3 sally john
|
||
|
||
id kid
|
||
1 billy
|
||
1 bobby
|
||
2 terry
|
||
2 susie
|
||
3 adam
|
||
|
||
How Is Information Accessed?
|
||
|
||
Tables are accessed through /rdb and shell commands issued at the COHERENT prompt or
|
||
from within shell or C programs. Here is a list of some common /rdb commands which are
|
||
used or mentioned in these examples.
|
||
|
||
Selected /rdb Commands
|
||
|
||
[TED COMMANA......00escerrevserseorereres
|
||
|
||
column, project.
|
||
row, select
|
||
|
||
mean......
|
||
|
||
jointable
|
||
|
||
sorttable
|
||
|
||
compute Do calculations on columns
|
||
subtotal... Subtotal selected columns
|
||
total. Total selected columns
|
||
|
||
Change the name of a column
|
||
Make a table line up properly
|
||
..Remove the first two header rows
|
||
. Report writer
|
||
|
||
..Mi-like table editor
|
||
|
||
/rdb commands are programs that read tables from the standard input and write tables to
|
||
the standard output. Suppose there's a table that looks like this:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 26 / Buchseite 16 ====
|
||
16 Relational Data Bases
|
||
|
||
Item Amount Cost Value Description
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
3 5 80 400 clamps
|
||
4 23 19 437 plates
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
v 5 175 875 scales
|
||
Then a sample query might be:
|
||
column Item Cost Amount < inventory
|
||
This produces:
|
||
Item Cost Amount
|
||
1 50 3
|
||
2 } 100
|
||
3 80 5
|
||
4 19 23
|
||
5 24 99
|
||
6 147 89
|
||
7 175 5
|
||
|
||
This is read aloud as: “Select the Item, Cost, and Amount columns from the inventory table.”
|
||
It's important to voice queries because people often type stuff in that they would never say
|
||
out loud.
|
||
|
||
The query:
|
||
row ‘Cost > 50’ < inventory
|
||
|
||
This produces:
|
||
|
||
Item Amount Cost
|
||
|
||
Value Description
|
||
|
||
3 5 80 500 clamps
|
||
6 89 147 16353.8 bunsen burners
|
||
% 5 175 1093.75 scales
|
||
|
||
This reads, “Select rows where the Cost column ts greater than 50 from the inventory table."
|
||
To put commands together:
|
||
|
||
column Item Cost Value < inventory | row ‘Cost > 50’
|
||
|
||
This produces:
|
||
|
||
Item Cost Value
|
||
3 80 400
|
||
6 147 13083
|
||
7 175 875
|
||
|
||
This is pronounced, “Select the Item, Cost and Value columns from the inventory file and
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 27 / Buchseite 17 ====
|
||
Relational Data Bases 17
|
||
|
||
select those rows where Cost is greater than 50.” Inside the apostrophes the < and >
|
||
symbols are pronounced less than and greater than respectively, whereas outside
|
||
apostrophes they are pronounced from and to. The pipe symbol *|" is pronounced and.
|
||
|
||
To take the mean of the result while listing each line:
|
||
|
||
column Item Cost Value < inventory | row ‘Cost > 50’ | mean -1l Value
|
||
This produces:
|
||
Item Cost Value
|
||
|
||
3 80 400
|
||
6 147 13083
|
||
7 175 875
|
||
|
||
4786
|
||
|
||
Creating Tables and Entering Data
|
||
|
||
There are many different ways to create tables; editors, programs, shell commands such as
|
||
sed or awk, etc. Most often, however, when /rdb tables are entered from scratch, ve, the
|
||
/rdb table editor is used. ve allows the creation of tables quickly and in a familiar and easy
|
||
way. It's a lot like vi. The first step in the creation of a table with ve is to create a screen
|
||
definition file with any editor. This can be accomplished with any editor. Here is a ‘screen’
|
||
file for the states file:
|
||
|
||
The States File
|
||
st < st >
|
||
state < state >
|
||
|
||
ve uses this screen file to create the table. The rules for screen files are simple:
|
||
1. Column names go inside the angle brackets.
|
||
2. Anything outside of angle brackets is just text that appears on the screen.
|
||
|
||
The space between angle brackets is the viewable window over the field, and isn't a
|
||
restriction on how wide the field can really be. After creating a screen file like this:
|
||
|
||
ve states
|
||
|
||
and the states file will be created. Let's say ve has been used to add new records to our
|
||
states table so that it looks like this:
|
||
|
||
st state
|
||
|
||
cA California
|
||
NV Nevada
|
||
|
||
NY New York
|
||
|
||
A mailing list can be created the same way, by making a ‘screen’ file and then using ve to
|
||
add a few rows:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 28 / Buchseite 18 ====
|
||
18 Relational Data Bases
|
||
|
||
Yet Another Mailing List
|
||
|
||
Name <name >
|
||
|
||
Street <address >
|
||
|
||
City <city >
|
||
|
||
State <st>
|
||
|
||
The command justify adjusts the mailing list, to make it appear neater. For example, the
|
||
command
|
||
|
||
justify < mlist
|
||
|
||
produces:
|
||
|
||
name address city st
|
||
|
||
Evan Main St. Santa Cruz CA
|
||
Rod Broadway Ithaca NY
|
||
|
||
The next command
|
||
|
||
column st name < mlist |
|
||
sorttable |
|
||
jointable - states
|
||
|
||
reads, “Select the st and name columns from mlist and join it with the states table.” It
|
||
produces the following:
|
||
|
||
st name state
|
||
CA Evan California
|
||
NY Rod New York
|
||
|
||
The sorttable command was silent. But it has to be there. Both files to be joined must be
|
||
sorted. The states file is already sorted. The dash in the jointable command means use
|
||
the standard input. just like the COHERENT join command.
|
||
|
||
Reports
|
||
|
||
For numeric information, /rdb's standard table output adjusted with a justify or trim
|
||
command is often sufficient, especially when combined with tabletotbl and the UNIX tbl
|
||
and the COHERENT nroff/troff formatters. In addition to these methods, /rdb has a
|
||
report command that uses a prototype report form and has built-in command processing
|
||
capabilities.
|
||
|
||
Let's look at a sample report form. It’s like the screen file for ve: text is outside brackets.
|
||
and column names are inside brackets. Other commands can also go inside the brackets.
|
||
Here's a report form for the mlist file:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 29 / Buchseite 19 ====
|
||
Relational Data Bases 19
|
||
|
||
<name>
|
||
<address>
|
||
< city >, <st>
|
||
<! date +8D !>
|
||
Dear < name >,
|
||
This is a computer chain letter.
|
||
I am also sending it to:
|
||
|
||
<! column name city < mlist |
|
||
row ‘name != “<name>"’ | justify !>
|
||
Bye, <! echo <name> I>.
|
||
|
||
Thus, the command
|
||
|
||
row ‘name ~ /Evan/' < mlist | report mlist.form
|
||
produces the following output:
|
||
|
||
Evan
|
||
Main St.
|
||
Santa Cruz, CA
|
||
|
||
09/03/89
|
||
Dear Evan:
|
||
This is a computer chain letter.
|
||
I am also sending it to:
|
||
|
||
name city
|
||
|
||
Rod Ithaca
|
||
Bye, Evan.
|
||
|
||
Arbitrary text goes outside the angle brackets; column names go inside angle brackets, and
|
||
any arbitrary command or shell program or shell command(s) can go between exclamation
|
||
marks within angle brackets, and you can still specify columns from the current record
|
||
therein. You can even have reports within reports.
|
||
|
||
The Big Text Field Problem
|
||
|
||
The “bug report,” “long text column,” and “every word indexed” problems are all facets of
|
||
the same situation. Let's say a file has some relatively short columns, and one or more long
|
||
text columns on which you'd like to use vi.
|
||
|
||
Take the case of a bug report data base with associated arbitrarily long narrative
|
||
descriptions: a solution is to keep the descriptions in a sub-directory called, for example,
|
||
bugreports, one file per record, with the file name being bugreports/recid where recid is
|
||
the record identifier from the current record. Then, a control key is mapped in the .vere file
|
||
(analogous to the vi's .exrc file) to the command vi bugreports/<recid>. This grabs an
|
||
identifying column from the record, constructs the name of the associated file(s), and pops
|
||
the user into vi on the named file(s). This is quite flexible even if there is more than one file
|
||
associated with each record, switching between ve files with a keystroke, thus effecting
|
||
multiple screens: map a control-key to write the record and switch the files, and another to
|
||
switch back.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 30 / Buchseite 20 ====
|
||
20 Relational Data Bases
|
||
|
||
A simple report makes a two column table with record id and word for each word in each
|
||
narrative, allowing for queries like Give me all the bugs mentioning word ‘xyzzy’:
|
||
|
||
#1/bin/sh
|
||
|
||
(echo “word id"
|
||
echo “---- --"
|
||
for i in [0-9]*
|
||
|
||
do
|
||
|
||
word < $i | awk ‘{print $1,"'$i'"}’
|
||
done) |
|
||
sorttable -u
|
||
|
||
Now records having a particular word can be found easily. If speed is a consideration, build
|
||
an(other) inverted index on the word/id concordance list just created:
|
||
|
||
ed bugreports
|
||
|
||
wordy > bugwords
|
||
|
||
index -mi -x bugwords word
|
||
|
||
echo xyzzy | search -mi -x bugwords word
|
||
|
||
This produces a list of record ID numbers on the standard output. Once you have the
|
||
record ID numbers, one more search is necessary to find the original record in the bugs
|
||
table. Of course, with the record ID numbers, no search is necessary to find the narrative,
|
||
because the file name ts the record id.
|
||
|
||
Non-Text Data Structures
|
||
|
||
Suppose a field is a picture, or a sound, or some other non-textual object. The /rdb
|
||
approach is to identify an object resource, with text, within a field in a table, describing the
|
||
type and location of the object. Fields from the current record can be referenced in the
|
||
-vere file by the same <column_name> specification used in the report program and
|
||
customized ve screen files.
|
||
|
||
Large Tables
|
||
|
||
Large tables are often as easily handled as small tables. When working with very large
|
||
tables some form of indexing is desirable: hash, inverted sequential secondary, binary
|
||
(sorted relations), or some form of tree (linked list).
|
||
|
||
The shell approach is to use the COHERENT directory structure as the first (few) levels of
|
||
tree index. One financial application using /rdb involves the 80-megabyte file of time series
|
||
from the International Monetary Fund. As distributed, it takes several large machine CPU
|
||
minutes to peruse this big file and extract a single time series. The file was divided into a
|
||
directory for each country and within each country directory. a file for each time series, with
|
||
the file name being the time series code as given by the IMF. Each of those time series files
|
||
is a /rdb file, with columns YR ANN Q1 Q2 Q3 Q4 and so forth. A separate “description”
|
||
file in each country directory has a line for each file in the directory. giving CODE
|
||
DESCRIPTION UNITS.
|
||
|
||
Thus, the time to retrieve any time series (if the country and time series code are known) is
|
||
independent of the size of the data base. Queries like “which countries have this time series
|
||
in common?” are answered with the Ils command. More than one level of index can of course
|
||
be implemented just by adding directory hierarchies.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 31 / Buchseite 21 ====
|
||
Relational Data Bases 21
|
||
|
||
COHERENT has many commands to traverse directory trees, and to add, delete, and
|
||
otherwise manipulate nodes. With this approach, nodes are tables, and the plethora of
|
||
COHERENT directory and file handling commands are all relational data base manipulation
|
||
commands.
|
||
|
||
Architectural Performance Enhancements
|
||
|
||
SQL
|
||
|
||
Learning to use the COHERENT utilities has a much greater value than learning yet another
|
||
special programming language. Once a small critical mass of COHERENT familiarity is
|
||
achieved, application development becomes little more than writing simple yet powerful
|
||
scripts to perform tasks which used to be laboriously performed by hand, or just not done
|
||
at all.
|
||
|
||
All these techniques comprise a marriage of the facilities that come with the COHERENT
|
||
system itself, and relational capabilities provided by /rdb.
|
||
|
||
This attitude of not reinventing the wheel is the basis of the shell and /rdb approach. All
|
||
COHERENT knowledge is knowledge about data bases, and experiences with data bases
|
||
teach more about COHERENT. That's why the combination of the /rdb extensions to
|
||
COHERENT and the shell command language is a 4GL most appropriate to the COHERENT
|
||
environment.
|
||
|
||
SQL is another language for querying a data base. It's used as the foundation for many
|
||
contemporary 4GLs. It does not use the stream/operator paradigm, but “nests” queries to
|
||
pass data from one operator to another. When SQL was developed, COHERENT had not yet
|
||
been invented, so an entire environment had to be developed to express queries. SQL is
|
||
another system to learn, with little use outside of itself. and typically no relation to the
|
||
operating environment surrounding it.
|
||
|
||
SQL does not specify any particular file format. Although there is an ANSI standard SQL for
|
||
expressing queries, implementors are free to store data however they want. In a way. this is
|
||
a contradiction, because getting away from these walls that stand between data is very
|
||
important, and was the principal reason that the concept of a data base came about. The
|
||
idea goes under the name of integrated and modeless software, and most recently,
|
||
interoperability.
|
||
|
||
There are reasons why SQL-based systems are popular, even desirable. SQL-based systems
|
||
are widely available and there is a large body of expertise also readily available. Many U.S.-
|
||
government agencies require access to corporate data bases via SQL, especially in the
|
||
defense industry. SQL is valuable in non-COHERENT environments. Partly because SQL is
|
||
difficult for novices to understand and use, SQL providers typically field a large, helpful
|
||
support organization. Of course, this drives the price up. and doesn’t adequately address
|
||
the needs that prompted the development of these tools in the first place: making non-
|
||
experts proficient and productive in the construction of basic data base applications.
|
||
|
||
SQL queries can be converted to shell scripts:
|
||
SQL COHERENT and /rdb
|
||
|
||
select coll col2 from filename......column coll col2 < filename
|
||
where column - expression ...... row ‘column == expression’
|
||
|
||
compute column = expression .compute ‘column = expression’
|
||
group by.. subtotal
|
||
having...... .row
|
||
|
||
order by column +.sorttable column
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 32 / Buchseite 22 ====
|
||
22 Relational Data Bases
|
||
|
||
+ unig
|
||
|
||
wwe =1
|
||
|
||
outer join.. jointable -al
|
||
update...... delete, replace
|
||
HESUING csccsscesscceses pipes
|
||
|
||
Fifth-Generation Systems
|
||
|
||
There is a distinction to be made between fourth-generation languages and CASE tools. The
|
||
programmer of a fourth-generation system must still specify the fundamental algorithms for
|
||
completing a task, perhaps at a higher level of abstraction, especially of data types. CASE
|
||
tools, on the other hand, require only a specification of the task, and generate not only the
|
||
code, but also the algorithm. CASE tools tend to be of very limited domain. An example
|
||
would be a screen layout tool. The developer draws the positions of the windows wanted.
|
||
and the tool generates the code to create the windows, manage the text and graphics inside
|
||
them, and deal with icons and menus.
|
||
|
||
Some graphical CASE tools are examples of what we might call 5GLs. Using a graphical
|
||
user interface, these tools allow applications to be built by example. Some force the user to
|
||
specify actions algorithmically, and some do not. There's even less agreement about what
|
||
constitutes a 5GL than there is about 4GLs.
|
||
|
||
The operator/stream paradigm has produced a simple, powerful, general purpose tool. It
|
||
allows one to prototype or generate a proof of concept in hours or days, when it might have
|
||
required weeks with C. Although the shell produces slower code than a third-generation
|
||
language. the increasing power of modern computers makes this a minor concern for many
|
||
tasks. This framework provides an easily visualizable way of manipulating large (or small)
|
||
amounts of structured data.
|
||
|
||
Although there is currently a shortage of utilities designed for general purpose use within
|
||
shell scripts, awareness of the potential of shell programming is spreading, and more
|
||
packages are being written outside of the traditional monolithic program tradition. In this
|
||
way, computing is coming full circle, returning to the original concepts of Von Neumann.
|
||
whose computing paradigm embodies the stream of sequential memory passing by the
|
||
operator of the central processing unit.
|
||
|
||
References
|
||
|
||
Kernighan B., Pike R.: The UNIX Programming Environment, Englewood Cliffs, NJ: Prentice
|
||
Hall, 1985.
|
||
|
||
Kochan S., Wood P.: UNIX Shell Programming. Hayden Book Company, 1985.
|
||
|
||
Prata S.; Advanced UNIX — A Programmers Guide. Indianapolis: Howard W. Sams and Co.,
|
||
Inc., 1985.
|
||
|
||
A. Winston: "4GL Faceoff: A look at Fourth-Generation Languages," UNIX/World, July 1986,
|
||
pp. 34-41.
|
||
|
||
Misra S., Jalics P.: “Third-Generation versus Fourth-Generation Software Development.”
|
||
IEEE Software, July 1988, pp. 8-14.
|
||
|
||
Manis R., Schaffer E., Jorgensen R.: UNIX Relational Database Management. Englewood
|
||
Cliffs, NJ: Prentice Hall, 1988.
|
||
|
||
Verner J., Tate G.: “Estimating Size and Effort in Fourth-Generation Development,” IEEE
|
||
Software, July 1988, pp 15-22.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 33 / Buchseite 23 ====
|
||
Relational Data Bases 23
|
||
|
||
Matos V., Jalics P.: “An Experimental Analysis Of The Performance Of Fourth Generation
|
||
Tools On PCs," Communications of the ACM, November 1989, pp. 1340-1351.
|
||
|
||
Manis R., Meyer M.: UNIX Shell Programming. Indianapolis: Howard W. Sams Inc.. 1987.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 34 / Buchseite 24 ====
|
||
24 Relational Data Bases
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 35 / Buchseite 25 ====
|
||
Section 3:
|
||
|
||
Commands, I/O, Pipes
|
||
|
||
/rdb commands are programs that read tables from the standard input and write tables to
|
||
the standard output. Once data are entered into tables, they are accessed through /rdb
|
||
and shell commands issued at the COHERENT prompt or from within shell or C programs.
|
||
This is an easy way to ask questions of, or query, the data base. Here is a list of some
|
||
common /rdb commands which are used or mentioned in the following example queries:
|
||
|
||
/rdb command Description
|
||
|
||
column, project... . Select only certain columns
|
||
|
||
row, select Select only certain rows
|
||
mean...... Compute the mean of selected columns
|
||
jointable . Join two tables
|
||
sorttable . Sort a table
|
||
compute Do calculations on columns
|
||
subtotal Subtotal selected columns
|
||
total. .. Total selected columns
|
||
rename ..Change the name of a column
|
||
justify. Make a table line up properly
|
||
headoff Remove the first two header rows
|
||
report . Report writer
|
||
Suppose there's a table that looks like this:
|
||
Item Amount Cost Value Description
|
||
|
||
1 3 50 150 rubber gloves
|
||
|
||
2 100 5 500 test tubes
|
||
|
||
3 5 80 400 clamps
|
||
|
||
4 23 19 437 plates
|
||
|
||
5 99 24 2376 cleaning cloth
|
||
|
||
6 89 147 13083 bunsen burners
|
||
|
||
7 5 175 875 scales
|
||
|
||
Then a sample query might be: 6
|
||
|
||
column Item Cost Amount < inventory
|
||
|
||
Which produces:
|
||
|
||
25
|
||
|
||
==== PDF-Seite 36 / Buchseite 26 ====
|
||
26 Commands, I/O, Pipes
|
||
|
||
Item Cost Amount
|
||
1 50 3
|
||
2 5 100
|
||
3 80 5
|
||
4 i9 23
|
||
5 24 99
|
||
6 147 89
|
||
y | 175 5
|
||
|
||
This is read aloud as: “Select the Item, Cost, and Amount columns from the inventory
|
||
table."
|
||
|
||
In another example, the command
|
||
row ‘Cost > 50’ < inventory
|
||
|
||
This is, ‘Select rows where the Cost column Is greater than 50 from the inventory table.”
|
||
This yields:
|
||
|
||
Item Amount Cost Value Description
|
||
3 5 80 400 clamps
|
||
6 89 147 13083 bunsen burners
|
||
a 5 175 875 scales
|
||
|
||
The next example puts the commands together:
|
||
column Item Cost Value < inventory | row ‘Cost > 50’
|
||
|
||
This is pronounced, “Select the Item, Cost and Value columns from the inventory file and
|
||
select those rows where Cost is greater than 50." This yields:
|
||
|
||
Item Cost Amount
|
||
3 80 5
|
||
6 147 89
|
||
7 175 5
|
||
|
||
Between the apostrophes, the < and > symbols are pronounced “less than” and “greater
|
||
than” respectively, whereas outside apostrophes they are pronounced “from” and “to”. The
|
||
pipe symbol ‘| ‘symbol is pronounced “and”.
|
||
|
||
To take the mean of the result while listing each line, do the following:
|
||
|
||
column Item Cost Value < inventory | row ‘Cost > 50’ | mean -1l Value
|
||
This yields:
|
||
Item Cost Amount
|
||
3 80 5
|
||
6 147 89
|
||
7 175 5
|
||
4786
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 37 / Buchseite 27 ====
|
||
Commands, I/O, Pipes 27
|
||
|
||
You can use the name select instead of row. The Korn shell has a select command, and
|
||
/rdb uses row as a synonym for select. We give the same program two names by using the
|
||
COHERENT link command In.
|
||
|
||
compute: Compute a New Result
|
||
|
||
The command compute lets you calculate one column as a function of other columns, or
|
||
constants. For example, you could calculate the Value column in your inventory table as
|
||
Onhand times Cost with this command:
|
||
|
||
compute ‘Value = Onhand * Cost’ < inventory
|
||
|
||
This yields
|
||
|
||
Item Onhand Cost Value Description
|
||
1 3 5 15 rubber gloves
|
||
2 100 1 100 test tubes
|
||
3 5 8 40 clamps
|
||
4 23 2 46 plates
|
||
5 99 3 297 cleaning cloth
|
||
6 89 18 1602 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
For a fancier example, add $5 to the Cost of item 4 only, and recompute the Value column:
|
||
|
||
compute ‘if (Item == 4) \
|
||
Cost += 5; Value = Onhand * Cost’ < inventory
|
||
|
||
This yields:
|
||
|
||
Item Onhand Cost Value Description
|
||
1 3 5 15 rubber gloves
|
||
2 100 1 100 test tubes
|
||
3 5 8 40 clamps
|
||
4 23 7 161 plates
|
||
5 99 F 297 cleaning cloth
|
||
6 89 18 1602 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
Note that the Cost of item 4 is now 7 (2+5). You can also write commands down the page.
|
||
From the line on which you open the apostrophe until you enter the closing apostrophe, the
|
||
shell will keep reading lines. You can do lots of powerful calculations with compute. See
|
||
the /rdb manual pages for compute, and read the awk tutorial in your COHERENT
|
||
documentation.
|
||
|
||
justify: Align Columns
|
||
|
||
Often when you type in a table, or for other reasons, the columns containing numbers
|
||
might be left justified. For example:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 38 / Buchseite 28 ====
|
||
28 Commands, I/O, Pipes
|
||
|
||
Item Onhand Cost Value Description
|
||
|
||
1 3 5 15 rubber gloves
|
||
2 100 1 100 test tubes
|
||
|
||
3 5 8 40 clamps
|
||
|
||
4 23 ng 161 plates
|
||
|
||
5 99 3 297 cleaning cloth
|
||
6 89 18 1602 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
In this inventory table, you may not like looking at number columns left justified. It is not
|
||
the way we usually see numbers in tables. But it is an easy way to enter data into a table
|
||
with a text editor because we do not have to space over to line up our numbers. To make
|
||
our table a lot prettier, the justify command is available. It right-justifies numbers and left-
|
||
justifies strings. It also blank fills the character columns, so that they can be placed in any
|
||
order and the columns to their right will still line up.
|
||
|
||
For example, it might be easier to enter the inventory table as shown previously. Then the
|
||
justify command can be used to right justify the numerical columns:
|
||
|
||
justify Onhand Value Cost < inventory
|
||
|
||
This yields:
|
||
|
||
Item Onhand Cost Value Description
|
||
|
||
i! 3 5 15 rubber gloves
|
||
2 100 ay 100 test tubes
|
||
|
||
3 5 8 40 clamps
|
||
|
||
4 23 7 161 plates
|
||
|
||
5 99 3 297 cleaning cloth
|
||
6 89 18 1602 bunsen burners
|
||
if 5 175 875 scales
|
||
|
||
Only the columns selected were justified, including their column headings. Item was not
|
||
selected and was not justified. Now if we project the columns in inventory in a different
|
||
order, the columns will line up correctly:
|
||
|
||
column Description Item Onhand Cost Value < inventory
|
||
|
||
which yields:
|
||
|
||
Description Item Onhand Cost Value
|
||
rubber gloves 1 3 5 15
|
||
test tubes 2 100 1 100
|
||
clamps 3 5 8 40
|
||
plates 4 23 2 Si
|
||
cleaning cloth 5 99 3 297
|
||
bunsen burners 6 89 18 1602
|
||
scales 7 5 175 875
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 39 / Buchseite 29 ====
|
||
Commands, I/O, Pipes 29
|
||
|
||
total: Compute Arithmetic Totals
|
||
|
||
To total columns of a table simply type:
|
||
|
||
total < inventory
|
||
|
||
This yields:
|
||
Item Onhand Cost Value Description
|
||
28 324 212 2980
|
||
|
||
Note that we have totaled the Item. Onhand, and Cost columns. Summing these columns
|
||
does not make much sense, but total, in this automatic or default mode, operates on all
|
||
numeric columns. Naming specific columns will result in your getting only those columns
|
||
totaled. Only numeric columns can be totaled.
|
||
|
||
The -1 option lets you see the whole table. (The 1 in -lis the letter “el”, not the number one.)
|
||
For example, the command
|
||
|
||
total -l Value < inventory
|
||
|
||
yields:
|
||
|
||
Item Onhand Cost Value Description
|
||
|
||
1 3 5 15 rubber gloves
|
||
2 100 1 100 test tubes
|
||
|
||
3 5 8 40 clamps
|
||
|
||
4 23 2 51 plates
|
||
|
||
s 99 3 297 cleaning cloth
|
||
6 89 18 1602 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
subtotal: Compute a Subtotal
|
||
|
||
To subtotal, enter the break column first, followed by the columns to be subtotaled. The
|
||
break column is the column watched by the program. If, on a new row, the value in the
|
||
break column is the same as the previous value in that break column, the values in the
|
||
other columns are added. But if the value in the break column changes (breaks), then
|
||
subtotal draws a line and prints the subtotals of the other columns. As long as the value in
|
||
the break column remains the same row after row, the values in the selected columns are
|
||
accumulated. When the break column's value changes, the subtotal is printed and a new
|
||
subtotal is started.
|
||
|
||
For example. we might have the following ledger table:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 40 / Buchseite 30 ====
|
||
30 Commands, I/O, Pipes
|
||
|
||
Account Date Debit Credit
|
||
101 820102 25000
|
||
101 820103 5000
|
||
101 820104 15000
|
||
130 820104 30000
|
||
150.1 820103 10000
|
||
211.61 820104 15000
|
||
211.1 820102 25000
|
||
211.1 820103 5000
|
||
|
||
In this example. Account is the break column and Debit and Credit are to be summed.
|
||
(This is done to foot the ledger at the end of an accounting period.)
|
||
|
||
subtotal -1 Account Debit Credit < ledger
|
||
|
||
This yields:
|
||
|
||
Account Date Debit Credit
|
||
101.0 820102 25000
|
||
|
||
101.0 820103 5000
|
||
101.0 820104 15000
|
||
101.0 25000 20000
|
||
130.0 820104 30000
|
||
|
||
130.0 30000 0
|
||
150.1 820103 10000
|
||
|
||
150.1 10000 0
|
||
211.1 820104 15000
|
||
211.1 820102 25000
|
||
211.1 820103 5000
|
||
211.1 ° 45000
|
||
|
||
Columns Debit and Credit are named on the command line, so only they are totaled, and
|
||
not column Date, which would be pointless to total. Note that the value in the break
|
||
column is carried down to identify the subtotal. The Account values are not subtotaled.
|
||
That would also be meaningless.
|
||
|
||
The -1 tells subtotal to output the whole table. not just the subtotals. Without the -l, we
|
||
would get only the subtotals. For example.
|
||
|
||
subtotal Account Debit Credit < ledger
|
||
|
||
yields:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 41 / Buchseite 31 ====
|
||
Commands, I/O, Pipes 31
|
||
|
||
Account Date Debit Credit
|
||
101.0 25000 20000
|
||
130.0 30000 0
|
||
150.1 10000 °
|
||
211.1 0 45000
|
||
|
||
Quoting Commands
|
||
|
||
Note that the apostrophe (') goes before and after the conditional expression in the row
|
||
command. This protects the expression from the COHERENT shell. The shell is the
|
||
program within the COHERENT system that reads the commands you type and executes
|
||
them. Without the apostrophe, the shell would see the left arrow (<) and think we were
|
||
inputting a table named 10. The apostrophe is also needed to put the whole expression
|
||
together as one argument for the row command. If you need to quote something within the
|
||
expression, use quotation marks ("). For example, if you had a column name with special
|
||
characters (including spaces) in it, you must put it in quotation marks. For example:
|
||
|
||
row ‘'"Net Pay" == "Gross-Pay"’ < payroll
|
||
|
||
A column name consists of upper- and lower-case letters, numbers, and the underscore
|
||
character ‘_'. Therefore, if you put special characters and spaces in column names, you will
|
||
have to keep putting the quotation marks around them every time you refer to them. (This
|
||
is true of C language versions of column and row. It is safest to stick with one-word column
|
||
names).
|
||
|
||
Note that we use a double equals ‘==" instead of just one ‘=. This comes from the C
|
||
language and the awk program, that the row and compute commands use. The rule is to
|
||
use the ‘=’ to mean, “Assign the value on the right of the equal sign, to the variable on the
|
||
left." Use the '==" to mean logically equal, as we used it in the row command. Another way
|
||
to remember this, is that you usually use the logical equal ‘==" in row commands, and the
|
||
assignment equal ‘=" in compute commands. In advanced usage, you will find that you
|
||
need both in row and compute for very powerful commands.
|
||
|
||
Pipes
|
||
|
||
Pipes *|' are a COHERENT shell mechanism that sends the output of one program to the
|
||
input of another program. This allows you to perform a series of operations on a table. You
|
||
now can begin to see the real power of this system. In a single line we can produce a report.
|
||
If you wished to select only rows where Value was greater than 100, but wanted to see only
|
||
the Description and Value columns sorted in alphabetical order, you could pipe the row
|
||
command's output into the column command, which would be piped into the sorttable
|
||
command like this:
|
||
|
||
row ‘Value > 100’ <inventory |
|
||
column Description Value |
|
||
sorttable
|
||
|
||
This yields:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 42 / Buchseite 32 ====
|
||
32 Commands, I/O, Pipes
|
||
|
||
Description Value
|
||
bunsen burners 1602
|
||
cleaning cloth 297
|
||
scales 875
|
||
|
||
The pipe symbol |" means that the output from the program to the left becomes the input to
|
||
the program on the right, or below. As with quotes, the shell will keep accepting lines
|
||
ending with pipes. Therefore, you can write long pipe programs down the page. which is
|
||
easier to read and debug. The sorttable program, without any columns named, defaults to
|
||
sorting on the first and subsequent columns.
|
||
|
||
Warning: Never use the same file as input and output in one command or pipe. If you want
|
||
to save the output that normally comes to your terminal screen in a file, use > tmp. The
|
||
tmp file name is a common name for a file that has only temporary use. It should always
|
||
be ok to remove it later. For example:
|
||
|
||
sorttable < inventory > tmp
|
||
|
||
You can then move tmp to inventory:
|
||
my tmp inventory
|
||
|
||
Now your inventory table is sorted. If you type:
|
||
sorttable < inventory > inventory
|
||
|
||
your inventory table will be zeroed out (have zero characters or lines in it). The reason is
|
||
that the COHERENT shell, in opening the inventory file for output. zeros the file's size.
|
||
Then, when the sorttable program (or any COHERENT program) reads it in, it gets EOF on
|
||
the first read. It closes the file, empty! You'll get the same disastrous effect even if you pipe
|
||
the output through several programs and then try to write it into the original input file. Do
|
||
not do it! Also, get in the habit of looking at your tmp file before moving it onto your
|
||
original good data. You may have made an error and be moving or copying bad data onto
|
||
good. Finally, be careful not to type
|
||
|
||
> file
|
||
when you mean:
|
||
< file
|
||
The first wipes out the file, rather than reading it.
|
||
|
||
Syntax: How To Enter Commands Correctly
|
||
|
||
In the manual, you will see a synopsis of each command and its syntax. Syntax is the rules
|
||
for forming a correct command. Semantics is what the resulting command will do.
|
||
Computer programmers are familiar with this way of expressing the syntax rules. If you are
|
||
not, read this chapter. We will start with simple syntax and go to complex. The simplest
|
||
syntax is a command with no options:
|
||
|
||
commands
|
||
|
||
You just type commands and you get all of the commands’ descriptions and their syntax
|
||
rules. Most commands require an input table. For example:
|
||
|
||
column < table
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 43 / Buchseite 33 ====
|
||
Commands, I/O, Pipes 33
|
||
|
||
Substitute the name of your table for the table in the syntax rule. But you type the column
|
||
< exactly as specified. If you have a table named inventory, you would type:
|
||
|
||
column < inventory
|
||
|
||
Many commands allow you to input tableorlist. This means they can handle both table and
|
||
list formatted files:
|
||
|
||
column < tableorlist
|
||
|
||
Options are placed in brackets ‘{ ]' because you do not have to type them unless you want
|
||
them. For example:
|
||
|
||
justify [ column ... ] < table
|
||
|
||
The brackets here mean that you can optionally name columns to be justified. The ellipsis
|
||
‘.... means that you can have many column names. But since there are brackets around the
|
||
column ..., you can also leave them out. In which case, all the columns would be justified.
|
||
Note that there are no brackets around the < table. This part is not optional. You must
|
||
have it to tell the COHERENT shell which file to open for input.
|
||
|
||
You should know that whenever you see < table you can also use a pipe to input a table
|
||
into the command:
|
||
|
||
cat table | justify
|
||
This has the same effect as:
|
||
justify < table
|
||
|
||
If you see a vertical bar ‘|" within brackets, it means or, not a pipe. Other commands give
|
||
lists of options in brackets. For example:
|
||
|
||
jointable [ -a[n] -n - ] [ -j[{n] column ] tablel [ table2 ]
|
||
|
||
This means that each option may or may not be selected. Note that there are brackets
|
||
within brackets. This means that if you chose the -a, for example, you have the further
|
||
option of adding a number n to specify which table number. The brackets around the -
|
||
jcolumn mean that the two strings go together, as well as being optional. The column
|
||
should be replaced by the name of one of the columns in one of the tables. Finally, the
|
||
second table is in brackets, meaning it is optional. But the manual page goes on to explain
|
||
that if it is not there. and the - option is not chosen, then the jointable command will get its
|
||
second table from the standard in.
|
||
|
||
The most complex syntax is for compute. It can only be hinted at with the rule:
|
||
compute ‘column = expression’ < table
|
||
|
||
expression can be quite complex. You must look at the manual pages for compute and awk
|
||
to get an idea of all of the things you can do.
|
||
|
||
COHERENT Shell Scripts
|
||
|
||
You can also put commands (including pipes) into a file and execute the file by simply
|
||
typing its name. These new commands are called views in the data-base literature because
|
||
they give you a particular view of your data. Use a text editor to type the commands into a
|
||
file, just as you would at the screen. Use a name for the file that you will remember and
|
||
that reminds you of what you are trying to do with the series of commands, like
|
||
weeklyreport. After leaving the text editor, type:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 44 / Buchseite 34 ====
|
||
34 Commands, I/O, Pipes
|
||
|
||
chmod 755 weeklyreport
|
||
or
|
||
chmod atw weeklyreport
|
||
|
||
This COHERENT command makes the file executable. chmod means change mode.
|
||
Whenever you want the series of commands that make up weeklyreport, just type:
|
||
|
||
weeklyreport
|
||
|
||
You can also use this new program in other COHERENT shell script files. If you want the
|
||
new program to be available to others, put it in /usr/local/bin, or some other bin that is in
|
||
the path of your users.
|
||
|
||
Suppose that at the end of each day, after making changes and updates to your inventory
|
||
file, you wanted to fix up the file. If you wanted to recompute the Value column, right
|
||
justify the number columns and left justify (blank fill the character columns); you could
|
||
pipe together compute and justify. But since you will need to perform these functions
|
||
often, you could create a program. The commands to fix up a table could be saved in a file
|
||
with an easy-to-remember name. For example, the fix command could look like this:
|
||
|
||
# fix is a little routine to compute
|
||
# and right justify the number columns
|
||
|
||
compute ‘Value = Onhand * Cost’ < inventory | justify
|
||
Remember to type:
|
||
|
||
chmod 755 fix
|
||
or
|
||
|
||
chmod at+w fix
|
||
to make it executable. If you don't, you'll see
|
||
|
||
Permission denied
|
||
|
||
when you type the name of the file. (You may also see this when you type the chmod
|
||
command if you don't have the right permissions.) To run fix just type its name:
|
||
|
||
fix
|
||
This yields:
|
||
Item Onhand Cost Value Description
|
||
1 3 5 15 rubber gloves
|
||
2 100 i 100 test tubes
|
||
3 5 8 40 clamps
|
||
4 23 2 46 plates
|
||
5 99 3 297 cleaning cloth
|
||
6 89 18 1602 bunsen burners
|
||
Ef 5 175 875 scales
|
||
|
||
You can see how easy it is to write programs in the COHERENT environment. This is called
|
||
shell programming. /rdb is an extension to the COHERENT system that adds data-base
|
||
commands to the COHERENT commands.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 45 / Buchseite 35 ====
|
||
Commands, I/O, Pipes 35
|
||
|
||
COHERENT is good at this kind of levels of power. With most systems, you are limited to
|
||
the functions the developers programmed into the system. With COHERENT and /rdb, you
|
||
are limited only by your own imagination.
|
||
|
||
There are other useful COHERENT commands. pr will set up your output with head lines,
|
||
and it will break on, and number, pages. nroff and troff can format your text and data for
|
||
attractive printouts.
|
||
|
||
There are many different ways to initially create tables: editors, programs, shell commands
|
||
such as sed or awk, etc. When /rdb tables are entered from scratch, ve, the /rdb table
|
||
editor, is often used. ve allows the creation of tables quickly and in a familiar and easy
|
||
way. It's a lot like vi. The first step in the creation of a table with ve is to create a screen
|
||
definition file with any editor. Here is a screen file for the states file:
|
||
|
||
The States File
|
||
st < st >
|
||
state < state >
|
||
|
||
ve uses this screen file to create the table. The rules for screen files are simple:
|
||
1. Column names go inside the angle brackets.
|
||
2. Anything outside of angle brackets is just text that appears on the screen.
|
||
|
||
The space between angle brackets is the viewable window over the field, and isn't a
|
||
restriction on how wide the field can really be. After creating a screen file like this:
|
||
|
||
ve states
|
||
|
||
and the states file will be created. Let's say ve has been used to add new records to our
|
||
states table so that it looks like this:
|
||
|
||
st state
|
||
|
||
CA California
|
||
NV Nevada
|
||
|
||
NY New York
|
||
|
||
A mailing list can be created the same way, by making a ‘screen’ file and then using ve to
|
||
add a few rows:
|
||
|
||
Yet Another Mailing List
|
||
|
||
Name <name >
|
||
Street <address >
|
||
city <city >
|
||
State <st>
|
||
|
||
This yields:
|
||
|
||
name address city st
|
||
Joe Main St. Santa Cruz CA
|
||
Bob Broadway Ithaca NY
|
||
|
||
To “Select the st and name columns from mlist and join it with the states table."" When we
|
||
run the command
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 46 / Buchseite 36 ====
|
||
36 Commands, I/O, Pipes
|
||
|
||
column st name < mlist |
|
||
|
||
sorttable |
|
||
jointable - states
|
||
it yields:
|
||
st name state
|
||
CA Joe California
|
||
NY Bob New York
|
||
|
||
The sorttable command was silent. But it has to be there. Both files to be joined must be
|
||
sorted. The states file is already sorted. The dash in the jointable command means use the
|
||
standard input, just like the COHERENT join command.
|
||
|
||
Report Writing
|
||
|
||
As with querying, report writing is also very easy. In fact. any query can be printed as a
|
||
report by directing its output to your printer. Likewise, any report can be a query by
|
||
directing it to your terminal (which is usually the default anyway).
|
||
|
||
For numeric information, /rdb's standard table output adjusted with a justify or trim
|
||
command is often sufficient, especially when combined with tabletotbl and the COHERENT
|
||
nroff/troff formatters. In addition to these methods, /rdb has a report command that
|
||
uses a prototype report form and has built-in command processing capabilities. It can be
|
||
used to write form letters from a mailing list, produce invoices, packing slips, purchase
|
||
orders, and so on.
|
||
|
||
Let's look at a sample report form. It's like the screen file for ve: text is outside brackets,
|
||
and column names are inside brackets. Other commands can also go inside the brackets.
|
||
Here's a report form for the miist file:
|
||
|
||
<name>
|
||
<address>
|
||
< city >, <st>
|
||
|
||
<1! date +8D I>
|
||
Dear < name >,
|
||
This is a computer chain letter.
|
||
I am also sending it to:
|
||
|
||
<! column name city < mlist |
|
||
row ‘name I= "<name>"’ | justify 1>
|
||
Bye, <! echo <name> I>,
|
||
|
||
This yields:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 47 / Buchseite 37 ====
|
||
Commands, I/O, Pipes 37
|
||
|
||
Joe
|
||
Main St.
|
||
Santa Cruz, CA
|
||
09/03/89
|
||
Dear Joe:
|
||
This is a computer chain letter.
|
||
I am also sending it to:
|
||
|
||
name city
|
||
Bob Ithaca
|
||
Bye, Joe.
|
||
|
||
Arbitrary text goes outside the angle brackets; column names go inside angle brackets. and
|
||
any arbitrary command or shell program or shell command(s) can go between exclamation
|
||
marks within angle brackets, and you can still specify columns from the current record
|
||
therein. You can even have reports within reports ...
|
||
|
||
Conclusion
|
||
|
||
In school you learned how to add, subtract, multiply, and divide. On the foundation of
|
||
those simple operations can be built all the rest of arithmetic. These four operations work
|
||
on numbers. A relational data base gives you a simple set of operations on tables of
|
||
information. With column, row, join, and so on you can do enormously powerful things, but
|
||
you will have to start thinking about what you want in terms of these operations.
|
||
|
||
Just as the add command does not care if it is adding apples or space shuttles, column
|
||
does not care what the information in the tables is. Therefore, these commands can
|
||
manipulate any data. This is an incredibly powerful idea that will take some time to get
|
||
used to. These relational operations are a well thought out. pretty complete set of all of the
|
||
things you will want to do with your data. It is up to your imagination to discover all of the
|
||
powerful, yet quick and easy tricks you can do with these extensions of COHERENT.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 48 / Buchseite 38 ====
|
||
38 Commands, I/O, Pipes
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 49 / Buchseite 39 ====
|
||
Section 4:
|
||
|
||
Entering Data into Tables
|
||
|
||
You have seen how to access your data, now we have to think of how to get your data into
|
||
the data tables. This is the real work of any data base system, so there are many tools to
|
||
make data entry as easy as possible.
|
||
|
||
ve: The Forms Editor
|
||
|
||
ve was created to serve as the principal data entry and data editing system for /rdb data
|
||
bases. It has much the same interface as the COHERENT text and program editor vi. We
|
||
wrote it that way so as to minimize the amount of user training required to bring a new data
|
||
entry person up to speed and to minimize the amount of confusion that could be caused by
|
||
switching back and forth between the COHERENT text editor vi and the /rdb forms editor
|
||
ve. Like the vi text editor, ve is a very powerful editor. Unlike vi, however, ve edits data in
|
||
forms rather than in the free-form manner of vi and ve has optional features you can
|
||
invoke to check the validity of your entries as you enter data, create an audit trail of your
|
||
entries (or changes), automatically number your rows, and much, much more. ve also
|
||
allows you to create /rdb tables directly from the forms editor and has a built in help facility
|
||
so that you can review any of its features or commands in the middle of your editing
|
||
session.
|
||
|
||
ve is called a forms editor. This means that you, the user, have control over the way your
|
||
screen looks and the placement of the various fields that you will enter data into on the
|
||
screen. The form definition of your ve screen is defined by a screen file or screen template
|
||
that you create. To create a screen file use any text editor to set up a one screen form that
|
||
consists of:
|
||
|
||
° The labels you want to have on the screen to prompt you for each column, and
|
||
. The other text or symbols you want on the screen to identify the row.
|
||
|
||
This procedure is called painting the screen. The labels on your screen are to be followed by
|
||
the actual names of your columns, enclosed in angle brackets <columnname>. This is much
|
||
the same format that you use to create a report template. For example, if you want to
|
||
create a telephone list form for data entry, you might create a screen form that looks like
|
||
|
||
this:
|
||
|
||
***Black Book****
|
||
|
||
Name <Name > Phone <Number>
|
||
|
||
Street <Street >
|
||
|
||
city <City > State <State> Zip <Zip >
|
||
|
||
The column names must be butted up against the left angle bracket. You can have spaces
|
||
after the column name. Because ve is designed to handle variable length columns (and
|
||
rows) you don't need to be concerned if the space you leave between the angle brackets in
|
||
your form isn’t enough to record all the data you plan to put into any particular column. ve
|
||
will allow you to enter data in columns of variable length. even if you exceed the space
|
||
available between the brackets on your screen, by shifting the window containing your data
|
||
if you key in more data than you have space for on the screen. ve also provides a scroll left
|
||
or right command and a zoom command so that you can see the full text of any column for
|
||
which there is insufficient space on the screen to display.
|
||
|
||
39
|
||
|
||
==== PDF-Seite 50 / Buchseite 40 ====
|
||
40 Entering Data into Tables
|
||
|
||
Once you have created the screen form. you then create the table by invoking ve. If you tell
|
||
ve to check the validity of your entries as you enter data into your table (with the -v switch),
|
||
then ve will prompt you for validation constraints when you create your table. You can
|
||
then set limits on column size, eligible characters to be keyed in, and table lookups in other
|
||
tables to cross-check the validity of your entry. These validation constraints can always be
|
||
modified later, so you do not have to get it perfect the first time.
|
||
|
||
ve also supports multi-user data entry or editing of the same table. It provides record
|
||
locking features that will allow you to avoid the problems that could be caused by having
|
||
two or more users attempting to edit the same row at the same time. With ve’s multi-user
|
||
record locking, only one user has access to a row at a time. Subsequent requests for a row
|
||
in use are inhibited, and a message is displayed.
|
||
|
||
This is a brief and general introduction to forms editing with ve. We have omitted a
|
||
discussion of the special data security features provided with ve, issues such as protected
|
||
fields in ve, instructions for optional cursor positioning, a ve command summary, a
|
||
discussion of the default list screen format, auxiliary indexing, and more. These are covered
|
||
in a subsequent chapter, in the ve manual pages, and in the on-line help screens of ve.
|
||
|
||
There are methods for data entry into /rdb tables other than ve.
|
||
|
||
Text Editor or Word Processor?
|
||
|
||
enter:
|
||
|
||
Another simple way to start a data table is to use a text editor or word processor. Type the
|
||
column head lines and dash lines and the first few rows of your table. Then save it. leave
|
||
the editor and try some of the query programs to see if you have set it up correctly. See the
|
||
section on Rules for Table and List File Set up. below.
|
||
|
||
This approach is good for starting your data bases and for small data bases, but at some
|
||
point a database may get too large for text editors. Then special purpose programs are
|
||
needed. Each has its advantages and disadvantages.
|
||
|
||
Mass Entry of Data
|
||
|
||
The enter command is an easy but limited way to type in a lot of data. For example. you or
|
||
your operators might have to enter card files, or mailing lists, or other bulk data. You may
|
||
not have time to train them to use a word processor or ve. With the enter program, they
|
||
just type
|
||
|
||
enter
|
||
|
||
and the name of the file. The program then prompts them for each column of each row.
|
||
which they type in. Each new row is simply appended to the table. It lets them go back to
|
||
an earlier column if they make a mistake. but there is no validation or browsing of the table.
|
||
It requires the lowest skill level and is the quickest to learn.
|
||
|
||
update: Update a Table
|
||
|
||
The update program lets you browse through a table file of any size. find a record with fast
|
||
access methods if you wish, edit the record found with any text editor you like, and return
|
||
the record to the file where it came from, or append the record to the end of the file if it is
|
||
too big to fit back in where it came from.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 51 / Buchseite 41 ====
|
||
Entering Data into Tables 41
|
||
|
||
Programs and Other Formats
|
||
|
||
Another great thing about COHERENT and /rdb is the ease of converting data files into
|
||
different formats. The /rdb table and list formats can be converted to and from all of the
|
||
other data base and word processor formats with simple shell, awk, sed, and other
|
||
COHERENT program tools. You can use other programs, instruments, computers, tapes.
|
||
floppy disks, networks, bar-code readers, natural-speech recognizers, expert systems, deep
|
||
space probes, and more to get your data, then simply transform it into /rdb table and list
|
||
format and use /rdb commands to do whatever processing you want. There are, therefore,
|
||
a multitude of ways to get your data in. After processing, you can transform it again and
|
||
send it back out.
|
||
|
||
Rules for Table and List File Set up
|
||
|
||
If you use ve to create and enter your tables you won't have to worry a lot about these rules.
|
||
But if you don't use ve, you'll need more detail about setting up a data file. Your data is
|
||
kept in files which can have either of two formats: table or list.
|
||
|
||
Table Format
|
||
|
||
A table looks like this:
|
||
|
||
Name Title Wage
|
||
Mary Pres. 4.98
|
||
Shawn V.P. 2.98
|
||
|
||
To repeat, there are only three rules for making tables that the /rdb programs can
|
||
understand. They are:
|
||
|
||
* There must be a single tab between each column.
|
||
|
||
° Put a column name, in the first line of the table, at the head of each column. Be sure
|
||
there is a tab between each column name.
|
||
|
||
s Put a dashed line as the second line of each table above each column. There must also
|
||
be a tab between each column's dashes.
|
||
|
||
° It is best if the dashed line is as wide as the widest string in each column, but it is not
|
||
necessary.
|
||
|
||
The justify command will set it to that width for you, if you wish. Remember to use the
|
||
dash or minus character ‘-’, not the underline character ‘_'.
|
||
|
||
There are several ways to make your tables pretty and to handle special problems. These
|
||
programs all require that you follow the three rules in order to work.
|
||
|
||
List Format
|
||
In addition to table format there is also list format, which looks like this:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 52 / Buchseite 42 ====
|
||
42 Entering Data into Tables
|
||
|
||
Name Mary
|
||
Title Pres.
|
||
Wage 4.98
|
||
Name Shawn
|
||
Title V.P.
|
||
Wage 2.94
|
||
|
||
The rules for lists are similar to those for tables:
|
||
|
||
The first character of a list-formatted file must be a newline. A newline character is
|
||
what you get when you hit your <return> key. It appears on the screen as a blank
|
||
line. Be careful that there are no unseen spaces or tabs in this first line that would
|
||
also look like a blank line, but would confuse the programs into thinking they are
|
||
looking at a table-formatted file. The programs use this first character to decide the
|
||
format of the file so they can handle both list and table-formatted files.
|
||
|
||
The file has exactly two columns. There must be a tab between the column name (i.e.,
|
||
Name) and the value (Mary).
|
||
|
||
Each row (or record. corresponding to a row in a table) must be separated from the
|
||
next row by a newline character. It looks like a blank line on the screen. (Note the
|
||
blank line between Wage [for Mary] and Name [for Shawn] in the list example). There
|
||
must also be a blank line at the end of the list file. Remember that a blank line has no
|
||
characters in it. The programs can detect these two newline characters in a row. That
|
||
is how they know that the end of the row (record) has been reached.
|
||
|
||
Tab Problems
|
||
|
||
The use of tabs to separate columns in /rdb has many advantages, but they create a few
|
||
problems. The advantages include:
|
||
|
||
Ease of input. When you press the tab key, the cursor jumps to the next column. This
|
||
is very natural to typists.
|
||
|
||
Tabs look nicer in tables then printable characters. They line up columns and are a
|
||
natural separator.
|
||
|
||
COHERENT utilities like awk, sort, and others, know about tabs and handle them
|
||
correctly.
|
||
|
||
File size. No extra characters are needed to fill out the table (unless the table is
|
||
justified).
|
||
|
||
No schema or other special file must be created and maintained to tell the programs
|
||
where data fields start and end, as is true with most other data base management
|
||
systems. COBOL programs, for example, are even worse. They have the exact length
|
||
of each field and record defined at the beginning of their code. This creates extreme
|
||
inflexibility. If you need to change any of your data, such as making a string longer or
|
||
adding a column, a COBOL program would have to be modified by a programmer and
|
||
recompiled. The output of one COBOL program is unacceptable as input to another
|
||
COBOL program unless the fields and their widths are exactly the same.
|
||
|
||
Some of the problems and their solutions are as follows:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 53 / Buchseite 43 ====
|
||
Entering Data into Tables 43
|
||
|
||
Seeing the Tabs
|
||
|
||
You can see the effect of the tab, but not the tab character itself. So, if you make an input
|
||
error, how do you know? You should often use the check program. It is especially
|
||
important for large files. It will report any lines that don’t have the same number of
|
||
columns (tabs) as the head line. It will also display the line to simplify finding where the
|
||
missing or extra tabs are located within the row. In most editors there are facilities for
|
||
seeing “I for every tab on the line or in the table respectively. Outside the editor you can
|
||
also use the see command or od -c table to see the special characters in the file. The see
|
||
command turns tab characters into “I. After running od, out comes a strange-looking table
|
||
showing each character including nonprinting characters converted so that they can be
|
||
seen. od means octal dump, but the -c option means to convert the bytes of the file into
|
||
their ASCII character representation. A tab is printed as: \t. as in the C programming
|
||
language.
|
||
|
||
Table-Width Problems
|
||
Your screen is usually 80 characters wide. What if a table is wider than that?
|
||
|
||
° Use ve to view your table. Ifa field is wider than the screen, you can shift the field left
|
||
and right. The default screen format tries to make a multiple column list of each field
|
||
of a record.
|
||
|
||
s Use the list format when you create your table. See the manual pages for listtotable
|
||
and tabletolist commands.
|
||
|
||
* You might decide simply to live with letting a long row in a table wrap around to the
|
||
next line on the screen.
|
||
|
||
* Break the table into two or more smaller tables. You may join them back with the
|
||
jointable command if you occasionally need to.
|
||
|
||
®: A table created by jointable, in a pipe, can be up to the maximum character width that
|
||
your available computer memory will hold.
|
||
|
||
° You can project only the columns you want to look at from your big table.
|
||
|
||
° You can get a wider terminal (some are 132 characters wide instead of the standard 80)
|
||
or printer (some allow compressed print).
|
||
|
||
Special Characters
|
||
|
||
You can use special characters in the column names (in the header lines). but it is best not
|
||
to. If you do, you will need to put quotation marks (") around the names when you type
|
||
them at the terminal to protect them from the COHERENT shell. The rules for quotation
|
||
|
||
marks, on COHERENT shell command lines, are: apostrophes (’...) absolutely protect
|
||
everything enclosed and quotation marks ("...") protect every character except the dollar sign
|
||
(8).
|
||
|
||
Therefore, put apostrophes around the whole string you are passing to row, compute, and
|
||
validate. Use quotation marks around column names that contain special characters
|
||
including spaces. For a complex example:
|
||
|
||
compute ‘"Item#" == 15 { len = length ("col 1") }’ < table
|
||
|
||
Note that Item# has a special character in it, and that col 1 has a space in it. All of these
|
||
must be quoted ("). Also, the entire command must be enclosed within apostrophes (’).
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 54 / Buchseite 44 ====
|
||
44 Entering Data into Tables
|
||
|
||
Even when you take these precautions, some COHERENT systems just don't like special
|
||
characters. It's best not to use them. Limit column names to alphanumerics, don't begin
|
||
them with numbers, and don't use any of the awk reserved words as column names.
|
||
|
||
Data Validation: How To Get Data Right
|
||
|
||
Data can be validated in many ways and at many times. ve allows you to specify validation
|
||
constraints at data entry time, checking each entry as it's made to make sure it passes tests
|
||
on what's allowed and what isn't. There is also a validate command which allows you to
|
||
specify the conditions that are invalid, and the error message that should print out when
|
||
the invalid data is found. The validate command is like the row and compute commands.
|
||
They all pass their instructions on to awk, which does all of the hard work. First a simple
|
||
example. If you had an inventory table like this:
|
||
|
||
Item# Onhand Cost Value Description
|
||
1 3 50 150 rubber gloves
|
||
2 100 x 500 test tubes
|
||
a -5 80 -400 clamps
|
||
4 23 19 437 plates
|
||
5 -99 24 -2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
There are several invalid values that have gotten into your table. You might want to check
|
||
that no Onhand item is less than zero. You can type this command:
|
||
|
||
validate ‘Onhand < 0 {
|
||
print "negative Onhand in line " NR
|
||
}’ < inventory
|
||
|
||
This yields:
|
||
|
||
Item# Onhand Cost Value Description
|
||
|
||
1 3 50 150 rubber gloves
|
||
2 100 xX 500 test tubes
|
||
|
||
3 5 80 -400 clamps
|
||
negative Onhand in line 3
|
||
|
||
4 23 19 437 plates
|
||
negative Onhand in line 5
|
||
|
||
5 ~99 24 -2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
y 5 175 875 scales
|
||
|
||
You can also put the command into a file and call it something like checkinventory. It
|
||
would then be a shell program that can be run regularly. See the validate command in the
|
||
manual for more examples and information.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 55 / Buchseite 45 ====
|
||
Section 5:
|
||
|
||
ve Form and Screen Editor
|
||
|
||
ve is a table editor designed for use on /rdb tables. Users who are familiar with the vi text
|
||
editor will enjoy the advantage of understanding ve's mode of operation and will already
|
||
know most of the ve commands.
|
||
|
||
This section describes the commands and what they mean, how to set up /rdb tables, how
|
||
to use the optional features to tailor ve to your application, and other considerations which
|
||
will help you in both designing and using your tables.
|
||
|
||
ve Commands
|
||
|
||
Most ve commands are described in detail in the following sections; a complete command
|
||
reference list is provided in the first ve on-line help page. ve's command language is very
|
||
much like the command language used by the vi COHERENT editor, in that both editors
|
||
use regular letters and symbols as commands. As such, the keys you hit are interpreted
|
||
either as commands to ve or as text that is being entered into your table depending on the
|
||
mode ve is in when you type them: insert mode or command mode. For a summary of the vi
|
||
editor, see the COHERENT Lexicon’s entry for elvis, which is COHERENT’s implementation
|
||
of vi.
|
||
|
||
Because ve is essentially a visual experience, the best way to understand it is by sitting
|
||
down at a terminal, creating a ve table, and experimenting with it.
|
||
|
||
Moving Around
|
||
|
||
The following table lists commands that move your cursor to a desired position on the
|
||
screen. It indicates whether a given command scrolls, if it knows about counts, and if it can
|
||
be used as a target.
|
||
|
||
Command Scroll Count Target
|
||
<Return> <tab> no yes no
|
||
B no yes yes
|
||
1 <space> yes yes yes
|
||
h yes yes yes
|
||
kj no yes no
|
||
“$ yes no yes
|
||
G no yes no
|
||
HL no no no
|
||
wbe yes yes yes
|
||
<> yes no no
|
||
fF; yes yes yes
|
||
|
||
The following describes each command in detail.
|
||
|
||
<Return> <tab>
|
||
Move the cursor to the next column in top-to-bottom, left-to-right order on your
|
||
screen. The <Return> key also works in insert mode.
|
||
|
||
==== PDF-Seite 56 / Buchseite 46 ====
|
||
46 ve Editor
|
||
|
||
B Moves the cursor to the next column in bottom-to-top, right-to-left order on your
|
||
screen.
|
||
|
||
1 <space>
|
||
Move the cursor one character to the right.
|
||
|
||
h Move the cursor one character to the left.
|
||
|
||
kj The k and j commands move the cursor, respectively, up and down the screen one
|
||
row.
|
||
|
||
“$ The * and § keys move the cursor to, respectively, the beginning and end of the
|
||
column.
|
||
|
||
G Move the cursor to the last row in your table. When you precede the G command
|
||
with a count, ve displays the row in the count position in the table. For example,
|
||
100G means “display the 100th row.”
|
||
|
||
HL The H key moves to the beginning of the first column on the screen; the L key
|
||
moves to the the beginning of the last column on the screen.
|
||
|
||
wbe_ The w key moves the cursor one word to the right: the b command moves the
|
||
cursor one word to the left; and the e command moves the cursor to the end of the
|
||
word.
|
||
|
||
<> The > command scrolls continuously through the column, left to right, until it
|
||
reaches the end. The < command scrolls continuously through the column, right to
|
||
left, until it reaches the beginning.
|
||
|
||
fF The f command looks left to right from your cursor for the character you specify;
|
||
the F command looks looks right to left from your cursor for the specified character.
|
||
The key you hit immediately after typing f or F is assumed to be the character you
|
||
are seeking. When ve finds the character, your cursor moves to its position in the
|
||
column. The ; command repeats your last f or F request. It remembers both the
|
||
character you last found, and the direction in which you were moving.
|
||
|
||
Occasionally, your screen will not be able to display all the data in a column or row because
|
||
its width exceeds that of the the screen window. To compensate for this, many movement
|
||
commands scroll left and right through the data, allowing you to see the entire contents of
|
||
columns which are too long for the screen space allowed.
|
||
|
||
Some commands let you to specify how many times ve repeats the command before it
|
||
repositions the cursor. These counts are entered as a number before the command. For
|
||
example, the command 41 moves the cursor to the fourth character in the column (left to
|
||
right). The command 2b moves the cursor two words to the left of your current cursor
|
||
position.
|
||
|
||
When ve beeps or flashes at you instead of moving. it means that the command is
|
||
inappropriate or that your cursor is already at your destination.
|
||
|
||
Displaying Your Data
|
||
|
||
There are two basic methods for displaying data on your screen. One is to display it
|
||
sequentially, which is the way they appears in the table. The other way is to look for
|
||
specific rows hy searching the table.
|
||
|
||
Sequential display: n, -
|
||
The n (or next) command displays the row in the table that immediately follows the
|
||
one now displayed. If n is the first command you give ve. it begins at the first row
|
||
in your table. The - displays the row in the table that immediately precedes the one
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 57 / Buchseite 47 ====
|
||
ve Editor 47
|
||
|
||
now displayed. If - is the first command you give ve, then it begins at the last row
|
||
in your table. Both sequential display commands wrap around to the
|
||
beginning/end of your table after the last/first row has been displayed.
|
||
|
||
Searching: /
|
||
When you use the / command, ve traverses your table row by row. looking for the
|
||
pattern you specified. It can repeat a search without making you retype the pattern
|
||
or character. If you have denied access to some columns by excluding their names
|
||
from your screen file, ve will omit these columns in its search.
|
||
|
||
The / command begin its search at the position of your cursor in the row and is
|
||
complete when the pattern you specify is found or when the entire table has been
|
||
examined. For example, to search for John Doe in your blackbook table (which is
|
||
described below), use the command /John Doe. For you to see what you are typing,
|
||
ve provides the last line of your screen to display the pattern as you type it in. You
|
||
can use your erase character to edit this line. When you are done typing in the
|
||
pattern, hit <Esc> or <Return> to tell ve that you are done. If John Doe is a
|
||
pattern in your table, then the row which contains John Doe will be displayed on
|
||
the screen.
|
||
|
||
Because ve remembers your search pattern, you need only type / and Esc> or
|
||
<Return>, to repeat your search of a specified pattern. Each time you enter a
|
||
search pattern, ve forgets the previous one.
|
||
|
||
Getting the Right Row
|
||
|
||
Usually the only requirement ve enforces when trying to match a search pattern to data is
|
||
that the entire pattern is contained in a single column, regardless of which column it is or
|
||
its position in the column.
|
||
|
||
Sometimes a search pattern will match data in many rows when you are looking for a
|
||
specific row. Choosing a search pattern which is unique to the row you want displayed will
|
||
speed up the search process. If this is not possible, you can limit the way ve searches by
|
||
forcing the pattern to match the beginning or end of a column, or by specifying a particular
|
||
column to which ve should limit the search.
|
||
|
||
Position matching: *, $
|
||
The character *, when it is the first character of a search pattern, tells ve that the
|
||
pattern following it must match data at the beginning of a column. The character
|
||
S. when it is the last character of a search pattern, tells ve that the pattern
|
||
preceding it must match data at the end of a column.
|
||
|
||
If you are searching for the ‘* character in the first position of your pattern, or the
|
||
‘S' character in the last position of your pattern, you must precede these characters
|
||
with a backslash (\).
|
||
|
||
Search column selection: m, M
|
||
Another way to limit your search is to make ve search only one column in each
|
||
row, using the m command. When you mark a specific column to be searched. ve
|
||
doesn't bother trying to match your search pattern with data in any other column.
|
||
As such, the search is quicker and the results are more likely to yield the desired
|
||
row on the first search.
|
||
|
||
To use the m command, simply position your cursor at the column you want to
|
||
search and hit m. All subsequent searches will be limited to data in that column
|
||
only. Hitting the m key on a different column changes the search column to that
|
||
column.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 58 / Buchseite 48 ====
|
||
48 ve Editor
|
||
|
||
If you have marked a search column and you want to go back to searching all of the
|
||
columns in each row, hit the M key to unmark your columns.
|
||
|
||
Inserting Text
|
||
|
||
Because most ve commands are ordinary characters, how do you tell when you are
|
||
executing a command, and when you are entering text?
|
||
|
||
When you type one of the insert commands listed below. ve switches from command mode
|
||
to insert mode. When you are in insert mode, everything you type is data and is displayed
|
||
on your screen. You know you're in insert mode because the <Insert/append mode>
|
||
message is printed at the bottom of your screen. If you don't see that message, then you are
|
||
in command mode.
|
||
|
||
The only way to get out of insert mode is to hit the <Esc> key. When you do this, ve erases
|
||
the insert message at the bottom of the screen and returns to command mode.
|
||
|
||
Several commands put ve into insert mode. Some commands destroy existing text
|
||
(indicated by ‘*’), whereas others add to it. All of the commands except O take effect on the
|
||
column at which your cursor is positioned, and, with the exception of the o command, at
|
||
the actual position of your cursor in the column. The C, c, and s commands mark your text
|
||
with a $ symbol to show you the text that will be changed. This symbol disappears when
|
||
you type over it. or when you hit the <Esc> key from insert mode.
|
||
|
||
The r or replace command is the only command which substitutes text without entering
|
||
insert mode. To use the r command, position your cursor at the character in the column
|
||
you wish to change, type r and the character to replace it. The r command can be used
|
||
with counts. For example, to replace the next four characters with the letter ‘x’, use the
|
||
command 4rx.
|
||
|
||
Command Means
|
||
|
||
a Append text to the right of the cursor
|
||
|
||
A Append text at the end of the column
|
||
|
||
i Insert text to the left of the cursor
|
||
|
||
I Insert text at the beginning of the column
|
||
|
||
o* Open the column and insert text at the beginning
|
||
oO Open a blank row
|
||
|
||
ctarget* Change the text between the cursor and target
|
||
|
||
c Change text from the cursor to the end of the column
|
||
s* Substitute the character at the cursor for text
|
||
|
||
R* Replace (overwrite) text character by character
|
||
Deleting Text
|
||
|
||
The delete commands let you delete entire rows and columns, partial columns, or
|
||
characters from your table:
|
||
|
||
Command Means
|
||
|
||
dd Delete the entire row
|
||
|
||
D Delete text from the cursor to the end of the column
|
||
x Delete the character(s) at the cursor
|
||
|
||
dtarget Delete text from the cursor to target
|
||
|
||
The x command also knows about counts.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 59 / Buchseite 49 ====
|
||
ve Editor 49
|
||
|
||
Targets
|
||
|
||
The insert command c and the delete command d require that you specify a target. A target
|
||
is exactly what it implies — a destination for the command being executed. Commands
|
||
that can be used as targets are listed in the section on moving around, The table below
|
||
shows sample d and c commands and what they mean when used with different targets.
|
||
|
||
Command Means
|
||
|
||
3dw Delete the next three words
|
||
|
||
de Delete to the end of the word
|
||
|
||
ce2fg Change the text to the second g found moving right
|
||
|
||
c* Change the text to the beginning of the column
|
||
|
||
cS Change the text to the end of the column
|
||
|
||
d; Delete text to character specified by last f or F command
|
||
|
||
All targets assume that the delete or change action begins from the position of the cursor
|
||
and counts must be specified before the actual target.
|
||
|
||
Yank, Put, and Undo
|
||
|
||
Sometimes accidents will happen when you are editing — you will hit the wrong key, or
|
||
decide that you really don't like a modification. You may even delete an entire row and then
|
||
realize it shouldn't have been deleted. Or perhaps you are entering rows which are almost
|
||
identical and you are sick of typing in the same thing over and over again. ve has a number
|
||
of commands that help you to efficiently deal with a change of mind after a change of text.
|
||
mistakes and repetitive data entry. These commands are known as yank, put and undo
|
||
commands.
|
||
|
||
Yank commands copy data from the row displayed on the screen into a special buffer. Put
|
||
commands put the yanked data from the buffer into the row on the screen.
|
||
|
||
Yanking data does not alter the row from which it is copied. Generally, once data has been
|
||
yanked, it can be put indefinitely without having to yank it again. Because ve remembers
|
||
only the text last yanked for each column displayed, yanking data from the same column in
|
||
another row overwrites previously yanked data in that column with the text that is currently
|
||
displayed. When entire rows are yanked or deleted, all yanked columns are overwritten
|
||
with the text in the displayed row.
|
||
|
||
Selected columns are yanked with the y command. To use it, position your cursor on the
|
||
column you want to yank and hit the y key. Different columns may be yanked from
|
||
different rows.
|
||
|
||
All columns on the screen can be yanked with the Y command, and it works by hitting the
|
||
Y key from any position on the screen.
|
||
|
||
Putting data replaces the data in the row or column being displayed with the data last
|
||
yanked by a y. Y, or dd command. Data can be put only in columns from which it was
|
||
yanked. For example. you can't yank text from a phone number column and put it in a
|
||
customer name column.
|
||
|
||
The p command replaces the data in the column at which your cursor is positioned with
|
||
data that has previously been yanked from that column.
|
||
|
||
The P command replaces the data in all columns currently displayed with data that has
|
||
previously been yanked from each column. Since veconsiders deleted rows to be yanked
|
||
text, using the P command after mistakenly deleting a row will restore it.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 60 / Buchseite 50 ====
|
||
50 ve Editor
|
||
|
||
ve remembers the data in the last column modified prior to the last command which
|
||
modified it. You can restore the data to that state by hitting the u key. The u command
|
||
works only for undo-ing modifications made to the row currently being displayed, and will
|
||
not undo what's already been undone.
|
||
|
||
For Your Information
|
||
|
||
The # command displays the list of topics in the on-line ve help files available for perusal.
|
||
To select a help file. position your cursor at the ==> symbol to the left of the desired topic by
|
||
using the J. <Return>, -, and k keys to move down and up the list. Then, hit any other key
|
||
(except q) to view your selection a page at a time. The J and <Return> keys display
|
||
successive pages, and the - and k keys display previous pages. Any other key (except the q
|
||
key) returns to the table of contents. Hit the q key to get back to your data display.
|
||
|
||
Other commands which provide assistance with or information about the current screen
|
||
contents:
|
||
|
||
° The v command displays the validation requirements for the column on which your
|
||
cursor is positioned.
|
||
|
||
e The t command prints the look-up table for the column upon which your cursor is
|
||
positioned, if such a table exists.
|
||
|
||
° Use the S command to redraw your screen if your deta display gets messed up.
|
||
|
||
® The z command draws a window under the column your cursor is on and displays the
|
||
contents of the column in the window. This command comes in handy when the data
|
||
for a particular column does not fit in the screen space allowed. The next key you hit
|
||
will erase the window.
|
||
|
||
Writing Rows
|
||
|
||
Whenever you change the data by adding or changing a row or column, you must use a W
|
||
or ZZ write command to make your changes or additions part of your table. When you use
|
||
the W or ZZ command, ve re-checks the data to make sure that all validation tests (if any)
|
||
have been passed.
|
||
|
||
When you are using the W command, and the data does not pass your validation tests (if
|
||
any). ve will complain and refuse to write your row in the table. In this case. your cursor
|
||
will land on the column which contains the bad data and you can fix it. If there are no
|
||
tests, or when the data passes your tests, ve will write your row in the table. and await your
|
||
next command.
|
||
|
||
The ZZ command is a quick way to write your row and exit from ve. If the row on the
|
||
screen has been added or modified and it passes your validation tests (if any), ve will put it
|
||
in the table before quitting. It will not tell you whether or not it writes the row.
|
||
|
||
If your data has been changed and you attempt to display a different row with a before
|
||
using the W command, ve will warn you that the row has not yet been written. Repeating
|
||
the command will override the warning, and the row on your screen will not be written in
|
||
your table.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 61 / Buchseite 51 ====
|
||
ve Editor 51
|
||
|
||
Getting Back to COHERENT
|
||
|
||
There are two kinds of commands which will get you back to COHERENT: shell commands
|
||
(!,%) and quit commands (q,ZZ). Shell commands let you talk to a new COHERENT shell
|
||
while your ve process is suspended in the background, waiting for you to return. Quit
|
||
commands end the ve process and return you to your COHERENT shell.
|
||
|
||
The % command displays a % symbol at the bottom of your screen and puts ve into
|
||
suspended animation. When you see your login prompt appear at the bottom of the screen,
|
||
COHERENT is ready for your command. To resume your conversation with ve, hit <ctrl-D>
|
||
(your EOF character). If you are not familiar with COHERENT processes and shells,
|
||
remember that it is easy to get carried away with COHERENT and forget that ve is still
|
||
patiently waiting for your return. You will know something odd is happening when you try
|
||
to log out and COHERENT keeps saying not your login shell. You must first return to ve and
|
||
give it a proper quit command. If COHERENT still complains, it means that you have
|
||
repeated the % command a succession of times. and you must repeat the <ctrl-D>q
|
||
sequence until you can log out.
|
||
|
||
The ! command before a COHERENT command executes the COHERENT command at the
|
||
bottom of the screen and then immediately return to ve. To read the results of your
|
||
COHERENT command, the message
|
||
|
||
[Hit RETURN to continue]
|
||
|
||
appears and ve awaits your response before it redraws your screen. The "%’ symbol, when
|
||
used in the ‘!' form of the shell command, is replaced with the name of the table you are
|
||
currently editing. To repeat a ! command. type !!.
|
||
|
||
Quit Commands
|
||
|
||
When you are finished using ve, you can use the q or ZZ command to exit. The only
|
||
difference between the q and ZZ commands is that q complains if the row on the screen has
|
||
not been written after a modification has been made. (A second q command simply exits
|
||
without writing the row.) The ZZ command will automatically write your row before exiting
|
||
ve.
|
||
|
||
Colon Commands
|
||
|
||
People accustomed to using the COHERENT editor vi are already familiar with colon
|
||
commands. Colon commands are always preceded by a colon (:). When the colon key is hit.
|
||
it appears at the bottom of the screen and the remainder of the command appears next to
|
||
the colon as you type it. You must enter at least the first letter of the colon command for it
|
||
to work (letters enclosed in [ ]'s show how much of the command you don't need to type).
|
||
You must end colon commands with <Return> or <Esc> to let ve know you are done.
|
||
|
||
Colon Command Is the Same As Described in Section
|
||
:nfext] n Sequential Display
|
||
:o[pen] °o Inserting Text
|
||
|
||
thfelp] # For Your Information
|
||
:wirite] Ww Writing Rows
|
||
|
||
:s[hell] % Shell Commands
|
||
s!command, !! ! Shell Commands
|
||
:q(uit] q Quit Commands
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 62 / Buchseite 52 ====
|
||
52 ve Editor
|
||
|
||
Macros
|
||
|
||
A macro command is defined as one or more ve or COHERENT shell commands mapped to
|
||
a single control key. Each time the control key is hit, the command or sequence of
|
||
commands defined by that control key will be executed.
|
||
|
||
Macro commands can be used to simplify an often-repeated sequence of commands into a
|
||
single keystroke. Because control keys are non-printable characters and cannot be
|
||
confused with potential data (unlike regular ve commands), they work from both command
|
||
mode and insert mode. The mode from which you execute the macro is restored after
|
||
successful completion of all the commands which define it. It is even possible to design a
|
||
set of macro commands that makes ve appear to be a single-mode editor. This might be
|
||
desirable for beginning users who find two edit modes confusing.
|
||
|
||
A maximum of 23 macro commands may be defined for the <ctrl-A> through <ctrl-Z> keys.
|
||
If your erase character or your interrupt character is a control key in this range, then it
|
||
(they) are excluded from the list of control keys available for macros. Macro commands that
|
||
include a second macro in their list of commands will replace whatever commands follow
|
||
the second macro in the list with the list of commands in the second macro. Embedding
|
||
macros in macros is confusing and it is not recommended.
|
||
|
||
Macro definitions are stored in a ve table named .verc. If you want to define your own
|
||
macros, this file must be in your home directory where it can be shared by all ve tables in
|
||
your account. If you don't have your own .verc file, ve will use its own.
|
||
|
||
The first column in the .vere file contains the letter which is hit simultaneously with the
|
||
control key to make the control key code. The second column in the .vere file is the
|
||
command or commands that are executed when the that key is hit. Four non-printable
|
||
commands which you may want to use in your macros are <Tab>, <Esc>, <Return>, and
|
||
<Backspace>. They should be indicated by \t. \e, \m, and \b, respectively. Below is a
|
||
copy of the default .verc file ve uses.
|
||
|
||
Control Key Command
|
||
#
|
||
ddn
|
||
°
|
||
ZZ
|
||
s
|
||
%
|
||
t
|
||
Ww
|
||
|
||
For example, let's say we're editing the blackbook table and we forgot to type in the area
|
||
codes for local phone numbers with 429 prefixes. If we mark the phone column using the
|
||
m command, and the macro
|
||
|
||
Pp /*429\e1 (408) \ew
|
||
|
||
reonQonp
|
||
|
||
is a row in our .verc file, then every time we hit <ctrl-P>, ve finds rows in which the first
|
||
three characters of the phone column are 429. ve will then insert (408) at the beginning of
|
||
the column and write the row.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 63 / Buchseite 53 ====
|
||
ve Editor 53
|
||
|
||
Shell Macros
|
||
|
||
If the command column in the .vere table begins with ‘!, then the remainder of the
|
||
command column, up to the end of the column or another ‘!’, is passed directly to the shell.
|
||
If the command contains valid column names enclosed in ‘<' and ‘>’, then the contents of
|
||
the named column(s) currently displayed on the screen will be substituted before the shell
|
||
is called.
|
||
|
||
Using the blackbook table, let's add a macro which will dial the emergency phone number
|
||
when we hit <ctrl-E>:
|
||
|
||
e tdial <phone>\n
|
||
Like regular shell commands, shell macros also expand ‘%' to the name of the current table.
|
||
|
||
For example, let's say we have a subdirectory named Personnel containing text files about
|
||
each employee in the personnel table. To keep these files distinct and unique, each is
|
||
named by the Social-Security number of the employee. See if you can figure out what the
|
||
following shell macro will do:
|
||
|
||
g Icat ‘echo % | cap‘/<ss number>\n
|
||
|
||
ve will echo the interpreted shell command on the message line, send it to the shell for
|
||
execution, and then print the
|
||
|
||
[Hit RETURN to continue]
|
||
|
||
message before refreshing your ve screen. Placing a ‘-' after the ‘!’ in the shell command line
|
||
will suppress the command echo, the pause and the screen refresh.
|
||
|
||
To see a list of the .verc commands in effect while you are using ve, hit <ctrl-?>.
|
||
|
||
The Command Line
|
||
|
||
The files ve uses and the way it displays and formats your data are determined by entering
|
||
a single command line at the prompt. The syntax for ve is:
|
||
|
||
ve [data [ -s [file] -h [file] -a [file] -v [file] -n[n] -fce -me -i]] [-b]
|
||
|
||
Dashes which are followed by a single letter are called switches (-s, -h, -a, -v, -m, -m, -i, -b).
|
||
Each switch tells ve to perform a specific job when it is invoked.
|
||
|
||
Words, symbols, and letters that directly follow each switch, when substituted for file
|
||
names, numbers, and characters, further define how ve should do the job indicated by the
|
||
switch. The word data shows where you would type in the name of your table; the file
|
||
words show where you would substitute the names of any files you might use. The n
|
||
symbol shows where you would substitute a number, and the c (as in -fc or -mc) shows
|
||
where you would put a letter or character.
|
||
|
||
The brackets ([ ]) are used to indicate items on the command line that are optional, and
|
||
should not be used in an actual command line. Note that with the exception of the word
|
||
ve, everything on the command line is optional. Thus, the command
|
||
|
||
ve
|
||
|
||
is a perfectly valid ve command that displays the on-line help file index.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 64 / Buchseite 54 ====
|
||
54 ve Editor
|
||
|
||
File Options
|
||
|
||
The first four switches in the command line apply to files that, with the exception of the
|
||
screen file, are in /rdb table format. They let the user define how the screen displays the
|
||
data (-s), separate the header lines from the data rows (-h), keep track of each modification
|
||
made to the table (-a), and impose various restrictions on the data as it is entered (-v). Each
|
||
of these switches can be used with the name of a file.
|
||
|
||
File Creation
|
||
|
||
How do we use the file options when the table or the files don't exist? The best and simplest
|
||
way is to let ve create, format and store the necessary files. This can be done in a single
|
||
command, so that all files are created and initialized at the same time. The following table
|
||
shows the conditions under which each type of file is created:
|
||
|
||
ve will create When
|
||
|
||
The table There is a screen or a header file
|
||
|
||
The header file There is a screen file and no table
|
||
|
||
The audit file There is a screen or a data or a header file
|
||
The validation file There is a screen or a data or a header file
|
||
The screen file Never — the user must do this
|
||
|
||
By examining the table above, it is apparent that the only file ve really needs in order to
|
||
create all of the other files, including the table, is a screen file. The preferred method for
|
||
initializing a ve table (starting up from scratch with no files), is:
|
||
|
||
A. Create a screen file. making sure to include all of the column names you want to be
|
||
|
||
part of your table.
|
||
B. On the ve command line, type in:
|
||
x The name of your table,
|
||
2. the -s switch with the name of the screen file you've just created,
|
||
3. and A file option switch followed by a name for each file you wish ve to
|
||
create.
|
||
|
||
For example, let's say we want to create a table named blackbook. Also, we want to impose
|
||
certain limitations on how the data is entered in some of the columns, and put these
|
||
limitations in a validation file called limits. So far, neither of these files exist.
|
||
|
||
The first thing we do is create a screen file which we name display. In the display file, we
|
||
include all of the column names we want in our blackbook table. When we finish making
|
||
our screen file, and type in the command
|
||
|
||
ve blackbook -s display -v limits
|
||
the following steps are performed:
|
||
|
||
A. ve looks in the blackbook file for the header rows. But blackbook doesn’t exist, so ve
|
||
creates it.
|
||
|
||
B. ve then reads the screen file we have created named display. It creates the header
|
||
rows from the column names in the screen file, and puts them in the new blackbook
|
||
table.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 65 / Buchseite 55 ====
|
||
ve Editor 55
|
||
|
||
C. ve creates a validation file named limits and uses the column names in the first
|
||
header row to create the rows in limits.
|
||
|
||
When ve is finished making all the new files, it draws your screen according to the display
|
||
screen file, and puts you in ve edit mode, exactly as if the files had already existed before
|
||
issuing the ve command.
|
||
|
||
Typing in the ve command line can be time consuming and tedious when using the file
|
||
option switches, especially if you are using any of the other switches as well. ve has a built-
|
||
in method of naming optional files associated with a table. When you take advantage of this
|
||
feature, the command line is greatly simplified.
|
||
|
||
Using the Default File Names
|
||
|
||
Whenever a ve command is issued with the name of a table, ve looks for files with names
|
||
that begin with the name of the table and end with each of the four file option switches.
|
||
These files are called default files. or files which are used by ve in the absence of specified
|
||
files. For example, consider the table named blackbook:
|
||
|
||
File Switch File Type ve Looks For
|
||
-s Screen blackbook-s
|
||
-v Validation blackbook-v
|
||
-a Audit blackbook-a
|
||
-h Header blackbook-h
|
||
|
||
If any of the default files exist. ve automatically includes them in the command line.
|
||
|
||
Specifying a file option switch with a file name overrides ve's inclusion of the existing
|
||
default file in the command line. As a corollary to this, files that are to be included in the
|
||
ve editing session which do not have default names must always be typed in the command
|
||
line, following the appropriate file option switch. For example, suppose you want to use a
|
||
screen file named myscreen instead of the default screen file named blackbook-s:
|
||
|
||
ve blackbook -s myscreen
|
||
|
||
Creating files from scratch also becomes much easier when using the default ve file names.
|
||
The same rules apply as above for creating files, but the names of the files do not need to be
|
||
typed in. Let's assume that we are starting out fresh with no files. We want to start a new
|
||
table named blackbook, with a validation file and an audit file. If we create a screen file
|
||
and name it blackbook-s, then the command line
|
||
|
||
ve blackbook -v
|
||
|
||
is all that is necessary to create the table named blackbook, and the validation file named
|
||
blackbook-v.
|
||
|
||
Automatic Row Numbering (-n)
|
||
|
||
The -n switch tells ve to give each row a unique numerical identifier automatically as it is
|
||
written. ve looks for and stores this number in the first column of each row.
|
||
|
||
If you are initializing a new table and you use the -n switch, you must reserve the first
|
||
column for this number. Of course, you may name the column anything you like — it just
|
||
has to be there. ve will start the row numbering at one.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 66 / Buchseite 56 ====
|
||
56 ve Editor
|
||
|
||
If your table already exists, ve figures out what to number new rows by scanning the first
|
||
column of each row in the table and adding one to the largest number it finds.
|
||
|
||
The n option to the -n switch, when substituted with a number, tells ve to start new rows
|
||
with that number. If the number you specify is less than the greatest numbered row in
|
||
your table, ve simply ignores your request, since it would mean duplicating existing row
|
||
numbers.
|
||
|
||
Once the -n switch has been specified in the command line for a particular table. it is not
|
||
necessary on subsequent calls to ve to include -n in the command line (unless you are
|
||
resetting the number with the n option), since ve keeps track of the largest numbered row.
|
||
The command
|
||
|
||
ve blackbook -n2001
|
||
|
||
is an example of using the -n switch to invoke automatic row numbering beginning with
|
||
2001. When you are editing a table that uses automatic row numbering. and the first
|
||
column is displayed on the screen, your cursor will not land on it. This is ve’s way of
|
||
making sure that you don't mess it up.
|
||
|
||
Start-up Mode Specification
|
||
|
||
The -m switch tells ve to enter the editing session in a particular mode. This mode is
|
||
specified by a character which must follow the -m switch, and can be i for insert mode, / for
|
||
search mode, or n for next mode. ve will return to this mode whenever a row is written. If,
|
||
for example, we want ve to start up in the insert mode, we would use the command:
|
||
|
||
ve blackbook -mi
|
||
|
||
Initialization Option
|
||
|
||
ve creates and maintains an index of the rows in your table. During ve edit sessions. this
|
||
index keeps track of which rows are being accessed by other users and which rows have
|
||
been deleted. When the table is quiet. ve uses the index to clean up the table by removing
|
||
the deleted rows and putting the updated rows in order. The index is also used to store the
|
||
last automatic row number (if applicable) and the column separation used by your table.
|
||
|
||
If your table has been modified using using a method other than ve, the index must be
|
||
recreated. This is done with the -i switch, which means initialize the table. It is not
|
||
necessary to use the -i option when you are creating the table.
|
||
|
||
The Screen File
|
||
|
||
A screen file is an ordinary text file which is created with any editor. It visually describes
|
||
the way the data are displayed during a ve edit session. If there is no screen file, ve
|
||
displays your column names in columns on the screen with the corresponding data
|
||
adjacent to the name. There are several reasons for using a custom screen file:
|
||
|
||
° It is the simplest and most accurate way to create your table.
|
||
° It allows you to take advantage of ve's security features.
|
||
|
||
. It allows you to customize or expand your column labels and helps to make your
|
||
screen display match specific hard copy forms.
|
||
|
||
° It allows you to rearrange the order or placement of your column names to
|
||
accommodate the size of data in the column.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 67 / Buchseite 57 ====
|
||
ve Editor 57
|
||
|
||
C it allows you to set the column on which your cursor will land each time a row is
|
||
displayed.
|
||
|
||
Screen File Format
|
||
|
||
The screen file should be formatted to look the way you want ve to display your data. Use
|
||
the following guidelines when creating a screen file:
|
||
|
||
A. For each column, indicate the beginning and ending positions for data display in the
|
||
screen file with the ‘<' and ‘>’ angle brackets, respectively. Both brackets must appear
|
||
on the same line. Type the name of the column between the brackets. If ve identifies
|
||
text surrounded by <>’s to be a valid column name, then data in that column will be
|
||
displayed between the brackets, and the brackets themselves will become blank.
|
||
|
||
B. If you are using the screen file to create a table, keep in mind that the names of all
|
||
columns must be included in the screen file. and that their top-to-bottom, left-to-right
|
||
order on the screen will determine the order in which ve arranges your data. (This
|
||
consideration is usually important only when you are planning to use automatic row
|
||
numbering or an audit file with your table. In that case, the uppermost, leftmost
|
||
column name will be assumed to be the name of the number column.)
|
||
|
||
If your table already exists, you must be sure that the column names in the screen file
|
||
are identical to those listed in the first header row of the table.
|
||
|
||
C. The entire screen file should be no longer than 23 lines and no wider than 80
|
||
characters, since this is the most information that standard screens accommodate (the
|
||
24th line is reserved by ve for messages).
|
||
|
||
Here is the screen file for our address-book table (blackbook):
|
||
|
||
*** Black Book ***
|
||
|
||
Name: <name > number: <phone >
|
||
Address: <street >
|
||
City/State/Zip: <city > / <state> / <zip >
|
||
|
||
Protecting Columns
|
||
|
||
Once a table has been created, a screen file can be used to selectively protect specific
|
||
columns by denying or limiting access to those columns. When you ve a table with a
|
||
screen file, only the data for columns which are named in the screen file will be displayed.
|
||
Thus, the simple omission of the names of confidential columns in the screen file protects
|
||
those columns from being displayed. Data in columns not named in the screen file are also
|
||
excluded from searching.
|
||
|
||
This feature comes in handy when you want to use ve to edit a specific subset of columns
|
||
and do not need to see the entire row.
|
||
|
||
By limiting access, we mean simply disallowing modification of designated columns. In the
|
||
screen file, column names preceded by an exclamation point (!) indicate to ve that they
|
||
cannot be modified.
|
||
|
||
To illustrate the security features, let's use the personnel table described earlier. For the
|
||
sake of this example. we'll add two columns for the name of the person to contact in an
|
||
emergency, and the phone number of that person. The header rows for such a table look
|
||
like this:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 68 / Buchseite 58 ====
|
||
58 ve Editor
|
||
|
||
employee ss number emp. date salary emergency phone
|
||
|
||
Let's assume that this table exists. and we simply want to update it. We want to be able to
|
||
search for employees by their name or their Social Security number, but we don't want
|
||
these columns modified. Also, because the salary column is confidential. we don't want it
|
||
displayed at all. Our screen file might look like this:
|
||
|
||
Company X-Y-Z Employee Information Card
|
||
|
||
Employee !<employee >
|
||
Social Security !<ss number > Date employed <emp. date >
|
||
|
||
In case of emergency <emergency > number <phone >
|
||
|
||
Setting the Cursor
|
||
|
||
Unless you are searching for a particular pattern, ve will position the cursor at the
|
||
uppermost, leftmost column name on the screen.
|
||
|
||
The column name on which your cursor automatically lands can be changed by preceding
|
||
the desired column name with an asterisk (‘*’). For example, if we were updating the
|
||
emergency name and phone number columns in the personnel table, we could make the
|
||
cursor land automatically on the emergency column as each row is displayed, by changing
|
||
the last line of the screen file to look like this:
|
||
|
||
In case of emergency *<emergency > number <phone >
|
||
|
||
The Validation File
|
||
|
||
A validation file describes column-by-column requirements that data must meet as it is
|
||
entered in the table. There are three different kinds of tests that you may force your data to
|
||
pass before allowing it to become part of your table: character range specification, column
|
||
length restriction, and table look-up.
|
||
|
||
Validation File Format
|
||
The validation file is a regular ve table. The header rows look like this:
|
||
name characters length table
|
||
|
||
For each column in your table which must pass one or more validation test. there is a row
|
||
in the validation file. The first column of each row in the validation file contains the name
|
||
of the table column.
|
||
|
||
Validation File Creation
|
||
|
||
ve can create your validation file, but you must supply the validation parameters. To make
|
||
this task easie;, ve calls on itself to edit the validation file, before opening up and displaying
|
||
your table.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 69 / Buchseite 59 ====
|
||
ve Editor 59
|
||
|
||
If you don't want to make a column pass validation tests, simply delete the row which
|
||
contains the column name from the validation file. When you are finished editing your
|
||
validation file with ve, your table will be displayed on the screen, and the validation
|
||
parameters will take effect immediately.
|
||
|
||
Character Range Specification
|
||
|
||
This validation option allows you to specify exactly which characters are acceptable (or not
|
||
acceptable) in a named column. For example, the ss number column of the personnel table
|
||
should be comprised of numbers and dashes. The employee column can be letters (upper
|
||
case and lower case), dashes, periods, commas, and blanks. The zip column of the
|
||
blackbook table must be numbers only.
|
||
|
||
ve allows you to specify these parameters in terms of ranges, or as single characters, in the
|
||
second column of your validation file. A range is defined as a low limit character and a high
|
||
limit character separated by a dash ‘-’". When more than one characters or range of
|
||
characters are specified, they are separated by a comma ‘,’. Using the above examples, the
|
||
character specifications for ss number is ‘0-9,-'; for employee is ‘A-Z,a-z, .-.,..'; for zip is ‘O-
|
||
9.
|
||
|
||
Let's say we have a column which can contain anything except upper case letters:
|
||
|
||
BZ O-9, Fy pepo tote Le mete Semele dele) hehe BSH Or Label ome om
|
||
|
||
The ‘!’ symbol, when it precedes a range or character, means not this range, or not this
|
||
character. Sometimes, as in the example above, the ‘!’ syntax can greatly simplify the
|
||
parameter list: ‘!A-Z’.
|
||
|
||
The ‘!’ can also be used to exclude specific members of a range. For example, one way to
|
||
specify all numbers except 8 is:
|
||
|
||
0,1,2,3,4,5,6,7,9
|
||
A simpler way is:
|
||
0-9,18
|
||
|
||
Column Length Restrictions
|
||
|
||
ve looks at the third column in each row of the validation file for column length limits.
|
||
These limits are used for several reasons. For example, we know that zipcodes should be
|
||
exactly five numbers long. We know that Social-Security numbers are exactly 11
|
||
characters. Data entered in these columns which are not the proper length make them
|
||
meaningless.
|
||
|
||
Also, it is sometimes the case that other limits indicate the necessity for a column-length
|
||
restriction. If, for example, we use the blackbook table to produce labels, then we should
|
||
restrict the length of the columns in the table to conform to the size of the labels.
|
||
|
||
Another use of column length might apply when you want to force a column to contain
|
||
data, but you don’t care (or don’t know) what the length should be. For example, in the
|
||
date column of the personnel table, you might require that something be entered, but it
|
||
might be of indeterminate length (October 1981. 10/1/81. 10/81, etc.).
|
||
|
||
Four specifications describe exactly how ve should pass data for the column length test:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 70 / Buchseite 60 ====
|
||
60 ve Editor
|
||
|
||
=n The column length must be exactly equal to n
|
||
<n The column length must be less than n
|
||
>n The column length must be greater than n
|
||
|
||
! The column can be blank (length 0)
|
||
|
||
Using the above examples, the column length for zip column in the blackbook table is =5,
|
||
which means exactly equal to five characters. If the size of our labels is 32 characters, then
|
||
the column length for the name and street columns of the blackbook table is <33, which
|
||
means less than 33 characters. The column length for the date column of the personnel
|
||
table might be >O0, which means there must be at least one character in this column.
|
||
|
||
When more than one of these specifications is used, they are separated by a comma ‘,’. The
|
||
‘Y column length specification, when used in conjunction with other specifications, tells ve
|
||
to ignore other length specifications if the column is blank. For example, if you specify the
|
||
zip column length mentioned above to be !,=5, then ve will allow you to skip over that
|
||
column — however, if you enter any data in this column, ve will force you to make it exactly
|
||
five characters long.
|
||
|
||
You can also indicate column length ranges by using the < and > specifications together.
|
||
(In fact, another way of saying !,=5 is !,<6,>4.) In the personnel table, the least number of
|
||
characters needed to specify date is four (1/82); the greatest number is 18 (September 11.
|
||
1949). You may wish to place an upper limit on this column simply to preclude the user
|
||
from typing in something silly like, “Gosh, I don't know, I guess Bud joined the firm round
|
||
about September, a few years back, because I first met him at the company’s Labor Day
|
||
barbeque.” In any case, the specification is >3,<19, which means any data in this column
|
||
must have more than three characters and less than nineteen characters.
|
||
|
||
Look-Up Tables
|
||
|
||
The fourth column in the validation file is for the name of a look-up table. If you use table
|
||
look-up validation on a particular column, then each time you enter data in that column, ve
|
||
compares it with data in the table. ve makes this comparison based on how you specify the
|
||
name of the table: if it is preceded by ‘!’, then it passes the table look-up test only if it is not
|
||
in the table; otherwise, it passes only if it is in the table.
|
||
|
||
ve updates all tables created from a table as you change, delete, and add data to columns in
|
||
that table. As such, you need to create each table only once. As long as you always use ve
|
||
to maintain your table, your tables will be current.
|
||
|
||
Table Creation
|
||
|
||
The vindex command is used to create look-up tables. To use vindex to create a new look-
|
||
up table (or overwrite an existing one), you must specify the name of the table and the
|
||
names of the columns in the table you want to index.
|
||
|
||
For example, if we want to create look-up tables for the ss number and the employee
|
||
columns of the personnel table, we would use the command:
|
||
|
||
vindex personnel employee "ss number"
|
||
|
||
vindex creates two files for each table it makes. using the naming convention column-A and
|
||
column-B. If the name of the column you are vindexing is longer than 14 characters, it will
|
||
be truncated to 14 characters before the -A and -B extensions are appended to the resulting
|
||
index files. Spaces are converted to ‘' and special characters which may be part of the
|
||
|
||
column name are omitted. In this example, the index files for the ss number table would be
|
||
named ss_number-A and ss_number-B. The ss number table is referred to in the
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 71 / Buchseite 61 ====
|
||
ve Editor 61
|
||
|
||
validation file simply as ss_number.
|
||
|
||
Decode Columns
|
||
|
||
An optional feature when creating and using look-up tables is the cross-indexing capability.
|
||
When you are creating a table for a column in a table, you can select a second column
|
||
which should be displayed when your data matches a pattern in the table. The displayed
|
||
data is called a decode column. The decode column must also be in the table, and, because
|
||
each indexed or key column can have only one associated decode column, vindex assumes
|
||
that data in the key column is unique. Similarly, when ve is used to update tables which
|
||
contain decode columns, the contents of the key column must be unique.
|
||
|
||
For example, consider the following states table:
|
||
|
||
state code name
|
||
|
||
NY New York
|
||
|
||
CA California
|
||
MA Massachusetts
|
||
|
||
In each row of the states table, the state code column contains a standard state
|
||
abbreviation: the name column contains the name of the state that corresponds to the
|
||
abbreviation. To create a look-up table on the state code column and cross-index the
|
||
name column, we use the command:
|
||
|
||
vindex states "state code" : name
|
||
|
||
The colon *:’ character in the command above is used to indicate that the following column
|
||
name (name) is a decode column for the column name preceding the colon (state code).
|
||
|
||
Unique Columns
|
||
|
||
We can use the ss_number table created previously to illustrate the use of look-up tables to
|
||
enforce unique column entries. In order to make sure that we don't enter duplicate
|
||
employee rows, we can make ve check each Social Security number as it is entered against
|
||
a table of those already in the table by specifying the name of the look-up table in the fourth
|
||
column of the validation row for ss number, using the ‘!’ symbol:
|
||
|
||
name characters length table
|
||
|
||
ss number 0-9,- 1,=11 !ss_number
|
||
|
||
In this case, the column passes the test if ve does not find an identical Social Security
|
||
number in the table. When we are editing the personnel table using ve, each time we add
|
||
a new Social Security number ve will look it up in the table: if it's already there, ve will
|
||
complain; otherwise, ve will add the new number to the table.
|
||
|
||
Column Inclusion
|
||
|
||
The blackbook table will illustrate how table validation can be used to make sure that the
|
||
data we enter in the st column are included in a table which lists all of the standard state
|
||
abbreviations.
|
||
|
||
We specify the name of the State_code look-up table in the blackbook validation file. Each
|
||
time we enter a state abbreviation in the st column of the blackbook table, ve will look it
|
||
up in the State_code table. If it's there, ve will print the name of the state next to the
|
||
abbreviation.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 72 / Buchseite 62 ====
|
||
62 ve Editor
|
||
|
||
name characters length table
|
||
|
||
st A-2 =2 State_code
|
||
|
||
Multi-User Considerations
|
||
|
||
ve is a multi-user table editor. This means that any number of users can be entering or
|
||
editing data in the same table at the same time. When a row is displayed on your screen, it
|
||
belongs to you until you release it by moving to another row, writing the row. or deleting it.
|
||
That means that anyone else who may be using the table at the same time will be prevented
|
||
from viewing or editing that row until you are finished with it.
|
||
|
||
Because ve knows which rows are in use at any given time. you will sometimes see the
|
||
message
|
||
|
||
1 other match(es) currently in use
|
||
|
||
when you search for a pattern in a row which belongs to someone else. This is to let you
|
||
know that the pattern is in your table, but the row which contains the pattern simply isn't
|
||
available.
|
||
|
||
When you use a sequential display command (n, -), ve will skip over rows which belong to
|
||
other users until it finds a free one. When ve has to skip over rows, it will let you know
|
||
how many. Similarly, the G command will let you know that it can't land ona specified row
|
||
because either it is currently in use or it has been deleted during the edit session.
|
||
|
||
/rdb-ve Compatibility
|
||
|
||
If you are planning to use /rdb on tables that are created and maintained by ve, taking the
|
||
following precautions when setting up your tables will help you avoid trouble later on.
|
||
|
||
Because many /rdb commands use table column names as command line arguments, care
|
||
must be taken to exclude symbols or words which have special meaning to the shell from
|
||
your column names. Specifically, stay away from the ‘|’, '#', and ‘!’ characters; if column
|
||
names can be confused with shell commands (ie., date, who), remember to protect them
|
||
from shell interpretation by enclosing them in quotes (") when you use them as arguments
|
||
to /rdb commands.
|
||
|
||
When using ve in a shell script, care must be taken not to access the original file until ve is
|
||
done with it. You can check for this by testing for the existence of a data+lck file. If the
|
||
data+ick exists, wait until it's gone.
|
||
|
||
Some /rdb commands use the awk program. which has its own command language. Below
|
||
is a list of awk words which should not be used as column names:
|
||
|
||
BEGIN exit in next sqrt
|
||
break exp index print substr
|
||
continue for int printf while
|
||
else getline length split
|
||
|
||
END bib log sprintf
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 73 / Buchseite 63 ====
|
||
ve Editor 63
|
||
|
||
Limits
|
||
|
||
Two basic size limits imposed by ve are the the maximum number of columns and the
|
||
maximum number of characters or bytes in each row. On the COHERENT installation, the
|
||
maximum number of columns is 66 and the maximum row length is 2,048 bytes.
|
||
|
||
ve will be able to accommodate most tables. If you need more than 66 columns in a row we
|
||
recommend that you create two separate tables, each with a common column, and use the
|
||
jointable command to merge the two tables after data entry has been completed.
|
||
|
||
There are no limits on the number of rows in your table or on the size of columns within a
|
||
row, as long as the 2,048 byte per row limit is not exceeded.
|
||
|
||
If you use the look-up table validation feature, you should be aware that a 64-byte limit is
|
||
imposed by truncation for the the lengths of the key and decode columns.
|
||
|
||
ve Validation
|
||
|
||
The validation table is used to specify, column by column, requirements that data must
|
||
meet as they are entered into the data table by associating a shell-level command with the
|
||
name of the column to be validated.
|
||
|
||
By default. all columns with associated validation commands are tested when the column
|
||
contents change or when the record is written, by executing the associated command and
|
||
using its return status to determine success or failure. A non-zero return status means the
|
||
test failed. ve will beep and the cursor will remain at the column until the contents are
|
||
modified to comply with the validation requirements.
|
||
|
||
Unless the # symbol precedes the command, the command is also executed whenever the
|
||
cursor passes through the field. unless nothing has changed since the last time the field
|
||
was passed. However, if the ‘@' symbol precedes the command in the validation file, the
|
||
command is executed even if nothing has changed. If the ‘#’ symbol precedes the command.
|
||
the command is executed only when the record is written (or deleted).
|
||
|
||
Unless the command is preceded by ‘“—’, the exit status of the command determines
|
||
whether the data in the field pass the validation test.
|
||
|
||
The shell that executes the validation command has some variables and constructs made
|
||
known to it by ve. Fields from the current record are passed to the validation command by
|
||
enclosing the field name in angle brackets, as in the screen file. The construct <@field> is
|
||
used to denote the contents of a field when the record was first displayed on the screen,
|
||
before any changes were made to it. The ‘%' symbol in the command line expands to the
|
||
current file name; the shell variables $ROW and SCOL are defined in the environment for
|
||
the executed shell to correspond to the start position of the current field, and SCOLEND is
|
||
defined as the first available white space after the field.
|
||
|
||
The validation file is a table with two columns:
|
||
|
||
column command
|
||
|
||
The first characters of the ‘command’ column have special meaning:
|
||
|
||
@ This tneans execute the command even if nothing in it changes This is typically
|
||
used in conjunction with the ‘!' prefix, to put something into the field without
|
||
having the operator type it in, like the date.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 74 / Buchseite 64 ====
|
||
64 ve Editor
|
||
|
||
_ This means ignore the exit status of the command and always pass validation. This
|
||
is used when the command to be executed doesn't really have anything to do with
|
||
validation. For example, it can be used to pop up a new window and display an
|
||
|
||
e. The window might be thrown away, producing a “fail” exit status, but we
|
||
really don't care,
|
||
|
||
! This means replace the field contents with the output of the command and can be
|
||
used to force the output of the date command into a field, or to calculate a field
|
||
based on one or more other fields.
|
||
|
||
# This indicates that the command should only be executed only when the record is
|
||
written or deleted, and not when the field is merely changed or passed through.
|
||
|
||
The standard error of the validation command is sent to the status line of the ve screen, so
|
||
you can customize the error message to include the field being validated or other arguments
|
||
passed to the validation command.
|
||
|
||
These commands used to be called “user exits” when this technique was used on IBM
|
||
systems.
|
||
|
||
Here's a sample validation file for the inventory file:
|
||
|
||
name command
|
||
|
||
number lookup inventory <number> $ROW $COLEND
|
||
Item unique Item % <Item> <number>
|
||
|
||
Amount. valid.chars <Amount> "[0-9]"
|
||
|
||
Value @techo "2k <Amount> <Cost> * 1.25 *p" | dc
|
||
|
||
This validation file looks complicated, but only because it's used to give examples of what
|
||
we've discussed. Suppose we want to look up the description for an inventory item, and
|
||
place it next to the record number. The first field, number, is validated by running the
|
||
program lookup with four arguments: first, the file name in which we want to look;
|
||
<number> is replaced by the contents of the number field, and $ROW and S$COLEND
|
||
become the location on the screen of the first available white space after the viewable
|
||
window over the number field as specified in the screen file. Bear in mind that SCOLEND
|
||
becomes the last column on the screen if there's no screen file, so it shouldn't be used
|
||
without a screen file.
|
||
|
||
The lookup program moves the cursor to the specified position and prints the Description
|
||
field:
|
||
|
||
#1/bin/sh
|
||
|
||
FILE=$1 NUMBER=$2 ROW=$3 COLEND=$4
|
||
cursor $ROW $COLEND
|
||
|
||
echo $NUMBER |
|
||
|
||
search -ms $FILE number |
|
||
|
||
column Description |
|
||
|
||
headoff
|
||
|
||
This guarantees uniqueness. Here's the unique program:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 75 / Buchseite 65 ====
|
||
ve Editor 65
|
||
|
||
#1/bin/sh
|
||
|
||
COLUMN=$1 FILE=$2 VALUE=$3 NUMBER=$4
|
||
|
||
FAIL=1 SUCCESS=0
|
||
|
||
exec 1>&2
|
||
|
||
if test -z "$VALUE"
|
||
|
||
then
|
||
echo -n $COLUMN may not be empty
|
||
exit $FAIL
|
||
|
||
fi
|
||
|
||
FOUND=‘row "$COLUMN == \"$VALUE\" && number != $NUMBER" < $FILE | \
|
||
column number | headoff’
|
||
|
||
if test ! -z "$FOUND"
|
||
|
||
then
|
||
echo -n “DUPLICATE $COLUMN $VALUE in $FILE (number $FOUND)"
|
||
exit $FAIL
|
||
|
||
fi
|
||
|
||
exit $SUCCESS
|
||
|
||
In all these commands, the standard error is directed to the status line. That's the purpose
|
||
of redirecting the standard output to the standard error with the first exec command. The
|
||
algorithm to determine uniqueness looks to see that there's no other record with this value
|
||
besides the current one.
|
||
|
||
One of the most common validation procedures is to limit the allowable characters. The
|
||
following script accepts a string to test. and a regular expression in the standard form
|
||
expected by the tr command of valid characters:
|
||
|
||
#1/bin/sh
|
||
exec 1>&2
|
||
VALUE="$1"; RE="$2"
|
||
|
||
SUCCESS=0 FAIL=1
|
||
LEFT=‘echo $VALUE | tr -d "$RE"’
|
||
|
||
if test -z "$LEFT"
|
||
|
||
then
|
||
exit $SUCCESS
|
||
else
|
||
echo $LEFT from $VALUE is not “$RE"“
|
||
exit $FAIL
|
||
fi.
|
||
|
||
The effect of this command is to delete the allowable characters from the field, and if there's
|
||
anything left over, they must be invalid characters, and the script exits with a FAIL status.
|
||
Similarly, the script for specifying invalid characters deletes the complement of the invalid
|
||
characters (the ones that are not invalid), and if there's anything left over exits with a FAIL
|
||
status.
|
||
|
||
The validation command for the Value column runs the de command to calculate Value on
|
||
the basis of Amount and Cost, putting the calculated result into the field. This is how you
|
||
compute one field based on the value of one or more others.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 76 / Buchseite 66 ====
|
||
66 ve Editor
|
||
|
||
To illustrate how the ‘#' can be used in the validation file, let's consider the case where we
|
||
need to update other tables /f and only if we actually make a change in the current table —
|
||
say for auditing purposes. Certainly we do not want to have to check each field as we pass
|
||
through it — it is costly and there is no guarantee that the user will commit the changes
|
||
made on the screen to the table. We only know and can only timestamp and record
|
||
changes as the user make that commitment by writing the row. Therefore, we use the ‘#’
|
||
validation key, which wakes up and performs the indicated operations only when records
|
||
are committed (changed. deleted, or added) to the disk. Because auditing does not apply to
|
||
a particular column, we can link it to any column in the validation file that doesn’t require
|
||
other validation.
|
||
|
||
We'll use a customers table as an example and we'll keep track of changes in contacts and
|
||
their phone numbers. First, the table layout:
|
||
|
||
cust_id name company street city st zip phone
|
||
|
||
And its verification table:
|
||
|
||
column command
|
||
|
||
cust_id @lookup customer "<cust_id>"
|
||
|
||
name #audit hist o "<@name>" "<€phone>"; audit hist n "<name>" "<phone>"
|
||
company #putkey customer “<cust_id>" "“<@cust_id>" "<company>"
|
||
|
||
city texchange “<city>" “Santa Cruz"
|
||
|
||
st @lookup st "<st>"
|
||
|
||
The audit command takes an output file name argument (hist), an initial key argument, (o
|
||
for old values and n for new values), and selected columns to be recorded. Thus, whenever
|
||
we write a row, audit gets the o key and the original contents of the name and phone
|
||
columns; then we hand audit an n key, with the current contents of the name and phone
|
||
columns. Let's see what audit does:
|
||
|
||
#1/bin/sh
|
||
USAGE="$0 audit_file key <[ @ ] column>... "
|
||
|
||
AUDITFILE=$1
|
||
shift
|
||
|
||
echo -n ‘date +%ytm#dtH8M%S’ >> $AUDITFILE
|
||
echo -n $1 >> $AUDITFILE
|
||
shift
|
||
|
||
while [ $# -gt 0 }
|
||
do
|
||
echo -n " $1" >> S$AUDITFILE
|
||
shift
|
||
done
|
||
echo "" >> $AUDITFILE
|
||
|
||
Another good example of when to use the ‘#' form of shell validation is when you're updating
|
||
hash keys and decodes created by jvindex. This is another time when you only want to
|
||
record changes which have been committed, rather than contemplated. The putkey
|
||
command updates hash keys in Jvindex'ed look-up tables. By executing putkey as key
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 77 / Buchseite 67 ====
|
||
ve Editor 67
|
||
|
||
columns are modified, we are able to maintain a fast and up-to-date index as we edit. In
|
||
the example above, putkey replaces the original contents of the cust_id column
|
||
(<@cust_id>) with the current contents of the cust_id column (<cust_id>) in the customer
|
||
look-up table. The jvindex command which created the customer look-up table is:
|
||
|
||
jvindex customers -ocustomer cust_id : company
|
||
Similarly, the lookup program used to display the cust_id calls getkey to locate the key
|
||
column cust_id in the lookup table customer. Here's what this version of lookup does:
|
||
#1/bin/sh
|
||
if [ $#-1t 2]
|
||
then
|
||
|
||
exit 0
|
||
fi
|
||
|
||
TABLE=$1; KEY="$2"
|
||
|
||
DECODE=‘getkey $TABLE $KEY’
|
||
STATUS=$?
|
||
|
||
if [ $STATUS -gt 0 ]
|
||
|
||
then
|
||
if [ "$DECODE" != "" ]
|
||
then
|
||
cursor $ROW $COLEND
|
||
echo -n “$DECODE"
|
||
fi
|
||
exit 0
|
||
else
|
||
exec 1>&2
|
||
echo “$KEY: no such $TABLE"
|
||
fi
|
||
exit 1
|
||
|
||
The exchange script substitutes the last argument for the first if the first argument is
|
||
blank, and puts the result in the city column. For example, pressing <Return> at the city
|
||
column will cause exchange to insert the words Santa Cruz. This is handy for columns
|
||
which are often, but not always, a single value. Here's what exchange looks like:
|
||
|
||
if "$1" = "" ]
|
||
|
||
then
|
||
|
||
echo $2
|
||
else
|
||
|
||
echo $1
|
||
fi
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 78 / Buchseite 68 ====
|
||
68 ve Editor
|
||
|
||
Control-Key Mapping
|
||
|
||
Control-key mapping allows you to define a set of ve commands or shell commands to be
|
||
executed when you strike the specified control key. Control-key definitions are usually
|
||
tailored to reflect often-repeated command sequences used by particular applications.
|
||
|
||
Both edit commands and shell commands may be combined for execution by a single
|
||
control key. For example, let's say you want a command to display a particular file (an
|
||
image. perhaps) during a ve edit session, and then refresh your screen when you are
|
||
finished examining it. Your .vere file might look like this:
|
||
|
||
CTRL-key command
|
||
|
||
P 1-pic part.snl12 | preview!s
|
||
|
||
In the command above, the first ‘!’ means that a shell command follows; the ‘-’ tells ve to be
|
||
silent, forcing the suppression of
|
||
|
||
Hit RETURN to continue
|
||
|
||
messages and shell newlines that roll your screen up. The remainder of the line, up to a
|
||
newline or another ‘!’, (whichever comes first) is handed directly to the shell. All information
|
||
after the ‘!’ are ve edit commands. In this example, ‘S’ will redraw the screen.
|
||
|
||
The ‘%' symbol in the mapped command means substitute the name of the current database
|
||
at this position. It works both interactively and in .verc shell commands. Try typing the
|
||
sequence :!cat % next time you're editing with ve.
|
||
|
||
You can pass column contents from the record being displayed by ve to the shell via the
|
||
-verc file. The syntax is similar to that used by the report program: column names
|
||
enclosed in ‘<’ and ‘>’ are replaced by the contents of the column when the command is
|
||
executed. We can illustrate a simple solution to the “long text field” problem. In this
|
||
example, ve is used to maintain a table of bug reports:
|
||
|
||
number date customer staff product
|
||
1 891212 cray evan /rdb
|
||
2 891107 sun wright ve
|
||
2 891107 sun wright ve
|
||
|
||
Because the description of bugs and fixes might be a few paragraphs, we do not want to
|
||
confine it to a column in a table. How, then, can we tie it to our data base and manipulate
|
||
it from ve?
|
||
|
||
We use the contents of the (unique) number column as the name of a text file which
|
||
contains the bug description. To keep these files in an orderly manner, we will collect them
|
||
in a separate directory and use the name of the data base to name the directory. To
|
||
distinguish between the name of the table and the name of the directory of reports, we'll
|
||
capitalize the first letter of the directory name (Bugs). Because the reports will be open-
|
||
ended text files, we will use a text editor to enter and modify their contents.
|
||
|
||
All of this can be accomplished by mapping a control key to a shell command which edits
|
||
the desired file name in the appropriate directory:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 79 / Buchseite 69 ====
|
||
ve Editor 69
|
||
|
||
e tvi ‘echo % | cap’/<number>\n
|
||
|
||
If we are on record number 43 and we hit <ctrl-B>, ‘%' will be replaced by bugs; <number>
|
||
will be replaced by 43; the shell will evaluate
|
||
|
||
‘echo bugs | cap’
|
||
to be Bugs. and the resulting path name, Bugs/43 will become an argument to vi.
|
||
Finally, use <ctrl-?> to see the contents of your .verc file from ve.
|
||
|
||
The approach of allowing broad shell access from within ve opens the door to all kinds of
|
||
powerful and time-saving data base routines that can be designed and implemented by
|
||
relatively naive users. The following rules should be followed to avoid pitfalls and
|
||
confusion:
|
||
|
||
1. Do not put spaces between the enclosing angle brackets and the column name
|
||
when you are specifying a column name for content substitution. This will cause ve
|
||
to assume that ‘<’ is redirect the standard input and ‘>’ is redirect the standard
|
||
output, and the column name will be passed to the shell uninterpreted.
|
||
|
||
2. Use ‘\’ to send the ‘%' symbol through to the shell without being replaced by the
|
||
name of the data base.
|
||
3. Use ‘-' after the ‘!’ in shell commands to suppress the normal messages and
|
||
|
||
newlines issued by ve and the shell. This is handy when you don't want to disturb
|
||
the current screen or window — for example, if you simply want to pop up a
|
||
subwindow in an unused portion of your screen and you do not wish ve to redraw
|
||
over it.
|
||
|
||
4. Use ‘!’ to ensconce shell commands between edit commands.
|
||
|
||
Command-line Options
|
||
|
||
ve recognizes the following command-line options:
|
||
|
||
-d This was implemented to prevent accidental deletion of rows, both by the dd
|
||
command, and by attempting to write a record in which each column has been
|
||
deleted.
|
||
|
||
+<cmd>
|
||
|
||
A more flexible way to start up ve with a particular command (as opposed to the -m
|
||
or mode option) is with the ‘+’ command. The remainder of the ‘+’ argument is
|
||
handed directly to ve’s command parser. Of course, because it is part of a shell
|
||
command, it must be constructed to escape shell interpretation. An example of this
|
||
is a command which searches for the word sun in the bugs table and appends the
|
||
word shine to it:
|
||
|
||
ve bugs +/sun\\eAshine\\e
|
||
|
||
The \e at the end of sun ends the search pattern; the \e at the end of shine exits
|
||
insert mode. The extra \’s are swallowed up by the hungry shell.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 80 / Buchseite 70 ====
|
||
70 ve Editor
|
||
|
||
Screen Size and Column Limits
|
||
The column limit of 66 fields has been expanded to 512.
|
||
|
||
ve screens can handle up to 158 columns by 64 rows. The size of the window in which ve is
|
||
executed determines how ve sets up default screens and uses blank space. To override the
|
||
absorption by ve of available window space, screen files should be terminated by a final
|
||
blank row. This row is interpreted by ve as the vertical position, after which the message
|
||
line is to be displayed.
|
||
|
||
User Column in Audit Files
|
||
|
||
The login name of the user is now recorded in the second column of the audit file. Existing
|
||
audit files must be modified to reflect the addition of the new column prior to appending
|
||
rows with the new version of ve.
|
||
|
||
Fast-Access Indexing From ve
|
||
|
||
Hash look-up on columns has been implemented for ve. Key columns are associated with
|
||
the row number stored in the -i file, effectively linking searches on keys to the G command.
|
||
The following rules apply for initiating key searches:
|
||
|
||
1. The key column must be marked with the m command prior to specifying the search
|
||
pattern.
|
||
|
||
2. Column contents must contain unique information.
|
||
|
||
3. The entire column must be entered in order for a key search to be initiated (which
|
||
makes it a good idea to keep key columns short).
|
||
|
||
Key columns are created with vindex by preceding the column name with the -k switch.
|
||
For example, to key the number column of the bugs table and have it decode to the
|
||
customer column:
|
||
|
||
vindex bugs -k number : customer
|
||
|
||
Searching for key columns is done in the ordinary way: simply precede the search pattern
|
||
with ‘/’. If it matches a hash key, the row is retrieved by it's indexed position in the table.
|
||
Otherwise, row-by-row pattern matching is performed. The method ve uses to find hits is
|
||
not obvious to the user (except in the case of large tables, where indexed searching is
|
||
significantly faster) and requires no additional expertise.
|
||
|
||
What Is the Cost of Indexed Searching?
|
||
|
||
When the last user exits an edit session on a table. the squeeze program is executed in the
|
||
background to clean up the table, putting records back in entry order and removing the
|
||
holes left by deleted records. This process reconstructs the table-i file. which keeps track of
|
||
row positions. Because indexed keys also use this information, they too must be updated
|
||
after the table has been “squeezed.” This process happens automatically when squeeze is
|
||
finished. The cost is the amount of time it takes to re-vindex each of the key columns for
|
||
the entire table.
|
||
|
||
To protect the table during the squeeze and vindex processes, a lock file (table+Ick) is
|
||
created. When both the squeeze and vindex processes are complete, the table+Ick file
|
||
disappears. It is important not to tamper with the table until the lock file is gone.
|
||
Depending on the size of the table and the number of indexed key columns which must be
|
||
updated, this can take a few minutes. So, the more keys you create, the longer it will take
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 81 / Buchseite 71 ====
|
||
ve Editor 71
|
||
|
||
to put it all back together after everyone has exited. For transaction processing, the best
|
||
strategy is to keep the table active (at least one ve user) during busy times.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 82 / Buchseite 72 ====
|
||
72 ~ve Editor
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 83 / Buchseite 73 ====
|
||
Section 6:
|
||
|
||
Data-Base Design
|
||
|
||
When you try to design your first data base, you are likely to be quite confused. Which data
|
||
go into which tables? Can you have just one big table? Should you have lots of little
|
||
tables? How do you find out? It turns out that there is a simple way to decide how to lay
|
||
out your data base. Once you learn it, any application will be easy. This chapter will show
|
||
you how.
|
||
|
||
One-to-One Relationships in One Table
|
||
|
||
When you look at your data. you will notice that some information has what we call a one-
|
||
to-one relationship. For example, each person has a first name, a last name, a birthdate, a
|
||
sex, an ID number, and so on. All of these items of information can be put into one table.
|
||
Here is such a table that is called employee:
|
||
|
||
Id First Last Birth Sex
|
||
|
||
nt Howard Ho 450503 Male
|
||
|
||
2 Jane Dobbs 540129 Female
|
||
|
||
The rule then is put all one-to-one relationships into a single table. Another example is
|
||
department:
|
||
|
||
Dept Name Head Address
|
||
|
||
1 act Jones Basement
|
||
|
||
2 sales White 4th Floor
|
||
|
||
One-to-Many Relationships in Two Tables
|
||
|
||
Another relationship is one-to-many. People have a one-to-many relationship with their
|
||
children. A person can have from zero to many children. Relational data base theory
|
||
insists that one-to-many relationships cannot be put into one table, but require two. In
|
||
addition to the employee table, you will need a child table:
|
||
|
||
Parent Name
|
||
1 Sally
|
||
1 Lynn
|
||
|
||
Note that Howard Ho (Id 1) has two children, Sally and Lynn. However, Jane Dobbs (Id 2)
|
||
has no children, because her Id (Parent) number is not in the child table. To put this
|
||
information back together, use the Jointable command:
|
||
|
||
jointable employee child
|
||
|
||
This yields:
|
||
|
||
73
|
||
|
||
==== PDF-Seite 84 / Buchseite 74 ====
|
||
74 Data-Base Design
|
||
|
||
Id First Last Birth Sex Name
|
||
1 Howard Ho 450503 Male Sally
|
||
1 Howard Ho 450503 Male Lynn
|
||
|
||
Here we have the two tables, employee and child, joined together on the employee Id and
|
||
the child Parent key columns. These connect the two tables for the jointable command.
|
||
|
||
Note that since Howard Ho has two children, he has two rows in the table. Also note that
|
||
Sally Dobbs was not included in the table because she has no children.
|
||
|
||
You can begin to see why we need to keep these kind of data in separate tables. We need
|
||
information on employees, even when they have no children. Of course, we could include
|
||
Sally Dobbs and leave her children column empty, but that will complicate processing.
|
||
|
||
More seriously, we have all of the information on Howard Ho repeated for each child. This
|
||
not only wastes space, but requires that when we update the table we have to find every
|
||
entry for Howard Ho and correctly make the update. The extra time and effort, plus the risk
|
||
of errors, make the single table approach unacceptable. Therefore, we must keep one-to-
|
||
many relationships in separate tables and join them together only when needed.
|
||
|
||
Many-to-many Relationships in Three Tables
|
||
|
||
There are also several many-to-many relationships. For example, students take zero to
|
||
many courses and courses have zero to many students. This relationship requires three
|
||
tables.
|
||
|
||
First we need a student table:
|
||
|
||
Student First Last Year
|
||
1 Jim Clark 2
|
||
2 Mary Witte 1
|
||
|
||
We also need a course table:
|
||
|
||
Course Credit Room Day Time
|
||
art-la 3 RB-8 MWF 10am
|
||
chem-1 4 HA-18 TTh 2pm
|
||
|
||
To connect these two tables, a third table is needed that we will call course.student:
|
||
|
||
Course Student
|
||
art-la 1
|
||
chem-1 2
|
||
chem-1 2
|
||
|
||
We can join these tables together with two jointable commands. First let's use the
|
||
jointable command to see individual joins:
|
||
|
||
jointable course course.student
|
||
|
||
This yields:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 85 / Buchseite 75 ====
|
||
Data-Base Design 75
|
||
|
||
Course Credit Room Day Time Student
|
||
art-la 3 RB-8 MWF 10am a
|
||
chem-1 4 HA-18 TTh 2pm 1
|
||
chem-1 4 HA-18 TTh 2pm 2
|
||
|
||
Next, the command
|
||
|
||
jointable -j Student student course.student
|
||
|
||
yields:
|
||
|
||
Student First Last Year Course
|
||
1 Jim Clark 2 art-la
|
||
1 Jim Clark 2 chem-1
|
||
2 Mary Witte 1 chem-1
|
||
|
||
All together now:
|
||
|
||
jointable -j Student student course.student | \
|
||
jointable -j Course - course
|
||
|
||
which gives us:
|
||
|
||
Student First Last Year Course Credit Room Day Time
|
||
|
||
1 Jim Clark 2 art-la 3 RB-8 MWF 10am
|
||
1 Jim Clark 2 chem-1 4 #HA-18 TTh 2pm
|
||
2 Mary Witte 1 chem-1 4 HA-18 TTh 2pm
|
||
|
||
So we can bring it all together when we want to see it, but we keep many-to-many
|
||
relationships in three separate tables.
|
||
|
||
Planning
|
||
|
||
When you look at your application, look for the kind of relationships that you have and
|
||
group your data accordingly. Continuing the college example above, we will also need tables
|
||
for instructors, rooms, and so on. There is a one-to-many relationship between instructors
|
||
and classes: instructors often teach several classes, but classes have one instructor (unless
|
||
there is team teaching).
|
||
|
||
Note that you have to think of exceptions. If the exceptions are very rare, you might choose
|
||
to ignore them. But if there are more than a rare instance of classes having more than one
|
||
instructor, it becomes a many-to-many relationship. Then you will need three tables,
|
||
because you will need a connector table.
|
||
|
||
Our college data base will also need a room table. What is the relationship between rooms
|
||
and courses? Can you see that it is one-to-many? A course is in only one room. (Is it
|
||
always? What about labs? Or are labs separate courses?) But rooms have more than one
|
||
course in them at different times, unless we have a terribly inefficient college. So how many
|
||
tables will we need? One-to-many requires two tables. Which tables do we need? In this
|
||
case a course table and a room table. The course table will have the room number in it.
|
||
but the room table will have no mention of the courses in it because there are many.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 86 / Buchseite 76 ====
|
||
76 Data-Base Design
|
||
|
||
To find the size of the room for each course, join the room table with the course table:
|
||
|
||
Course Credit Room Day Time Teacher
|
||
art-la 3 RB-8 MWF 10am 3
|
||
chem-1 4 HA-18 TTh 2pm 1
|
||
cs-101 4 DB-1 MWF 2am 2
|
||
econ-1 3 RB-8 TTH ipm 2
|
||
his-10 3 HA-18 MWF liam 3
|
||
|
||
And we need a Room table:
|
||
|
||
Room Type Size Hall
|
||
|
||
DB-1 Lecture 250 Daddy Bucks
|
||
HA-18 Lab 17 Hillary Addler
|
||
RB-8 Tacky 23 Roberta Bucks
|
||
|
||
Then, use the commands sorttable and jointable to combine them:
|
||
|
||
sorttable Room < course |
|
||
jointable -j Room - room |
|
||
column Course Room Size > room.size
|
||
|
||
This creates the table room.size, as follows:
|
||
|
||
Course Room Size
|
||
cs-101 DB-1 250
|
||
chem-1 HA-18 17
|
||
his-10 HA-18 17
|
||
art-la RB-8 23
|
||
econ-1 RB-8 23
|
||
|
||
So, it turns out that designing a data base is easy. Just practice thinking about these
|
||
principles with different applications.
|
||
|
||
Normalization
|
||
|
||
The approach we have just discussed is the easiest way to think about designing your data
|
||
base. However, most of the data base literature approaches the problem from a different
|
||
angle. To help you understand that literature, these other approaches are discussed in the
|
||
following sections. It is more technical and can be skipped on first reading, or if you are
|
||
just beginning to use data bases. In the technical relational data base literature, this
|
||
process of correctly grouping data into tables is called normalizing.
|
||
|
||
Functional Dependency
|
||
|
||
Before discussing normalization, several concepts must be understood. Functional
|
||
dependency refers to whether the data in one column determine the data in another. In
|
||
other words, if you know the data in one column, can you tell what the data in another
|
||
column will be? If the data in one column are repeated, are the corresponding data in the
|
||
other column also repeated? If so, there is a functional dependency, otherwise not.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 87 / Buchseite 77 ====
|
||
Data-Base Design 77
|
||
|
||
For example, look at these two tables. First, the room.size table we previously created:
|
||
|
||
Course Room Size
|
||
cs-101 DB-1 250
|
||
chem-1 HA-18 17
|
||
his-10 HA-18 17
|
||
art-la RB-8 23
|
||
econ-1 RB-8 23
|
||
|
||
Note that when a value in the Room column is repeated, the corresponding Size value is
|
||
also repeated. (See RB-8 is in the Room column with the same Size of 23. Also the same
|
||
for HA-18 and 17). Therefore, Room functionally determines Size or an equivalent way of
|
||
saying it, Size is functionally determined by Room. Ordinarily, we do not want to have
|
||
tables with functional dependencies in them, It is acceptable here, because we used a join
|
||
to put this table together. It is a query of our data base and not a proper table of the data
|
||
base.
|
||
|
||
Keys
|
||
|
||
Key columns are the unique identifiers of each row in the table. The key column or
|
||
columns of a table should always determine each of the other columns of the table. The
|
||
function of a key is to uniquely identify the data in the other columns. So the rule is that
|
||
only key columns can functionally determine other columns. Nonkey columns should not
|
||
functionally determine other columns in a normalized data base.
|
||
|
||
Universal Relation
|
||
|
||
The opposite of normalization is the universal relation. Imagine one large table that has all
|
||
of the tables joined together. It has all of the columns of all of the tables across the top. It
|
||
is the worst case of a unnormalized data base. Why? What is wrong with such a table?
|
||
|
||
We need to avoid unnormalized tables because they create severe problems for us.
|
||
|
||
Redundancy Problems
|
||
|
||
One problem is that we have a lot of redundant data. Look at the room.size table again
|
||
and note that the size information for each room is repeated:
|
||
|
||
Course Room Size
|
||
cs-101 DB-1 250
|
||
chem-1 HA-18 17
|
||
his-10 HA-18 17
|
||
art-la RB-8 23
|
||
econ-1 RB-8 23
|
||
|
||
This takes up more space than necessary and slows down the programs that must process
|
||
it.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 88 / Buchseite 78 ====
|
||
78 Data-Base Design
|
||
|
||
Update Problems
|
||
|
||
Another problem is the extra work and errors that result from trying to update such a table.
|
||
Suppose we add more chairs to HA-18. We have to update the new Size twice. In this
|
||
simple table, that is not much work, but in a large data base it is overwhelming. And what
|
||
happens when we make an error in our updating? It is hard to find and correct. After a
|
||
while, we will not know which conflicting value is correct. Our data base will become
|
||
hopelessly corrupted.
|
||
|
||
Insert and Delete Problems
|
||
|
||
There are also insert and delete problems. Suppose we want to add a room and its size to
|
||
this data base. If it does not yet have a course in it, we can't put it into the table unless we
|
||
give it a blank course. This creates problems when searching and joining. How do you
|
||
handle blank or null values?
|
||
|
||
Likewise with deleting. What if a course is still assigned to the room after the building has
|
||
been demolished? You don't want to drop the course, but you need to delete the room from
|
||
the data base.
|
||
|
||
First Normal Form
|
||
|
||
For relational functions to work, tables must be simple or, as it is called in the literature,
|
||
normalized. There are a number of steps to simplifying, or normalizing, a table. Most
|
||
importantly, you must never have a variable number of columns in a table. For example, in
|
||
a file of college employees, you might be tempted to have a column for the first name of the
|
||
|
||
children of employees:
|
||
|
||
Emp# Name Dept Child
|
||
|
||
1 Martin 1204 Sally, Fido
|
||
|
||
2 Moore 1339
|
||
|
||
3 Mapes 1045 Jan, Shawn, Peter, Barbara
|
||
|
||
This creates many problems, not the least of which is that the relational functions will not
|
||
work. The answer is to have two files, one for employees and another for their children.
|
||
The child file would look like this:
|
||
|
||
Peter
|
||
3 Barbara
|
||
|
||
When you need to put the two files together. you do so with a join (jointable in /rdb
|
||
because there is a COHERENT command named join, which works on files without
|
||
headers). This is another way of saying that one-to-many relations must be represented in
|
||
two tables. When all of the one-to-many relations are in separate tables, we say that the
|
||
data base is in first normal form,
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 89 / Buchseite 79 ====
|
||
Data-Base Design 79
|
||
|
||
Second Normal Form
|
||
|
||
Both second and third normal forms require that nonkey functional dependencies be
|
||
removed by creating additional tables. In the case of second normal form, we look for
|
||
dependencies on columns within the key. Keys can consist of more than one column. For
|
||
example, consider a grade table:
|
||
|
||
Course Student Grade
|
||
|
||
art-la 1 3
|
||
art-la 4 4
|
||
chem-1 1 3
|
||
chem-1 2 2
|
||
chem-1 3 2
|
||
cs-101 2 1
|
||
cs-101 4 4
|
||
econ-1 i 3
|
||
econ-1 2 3
|
||
econ-1 3 2
|
||
his-10 1 3
|
||
|
||
Note that it takes two columns to make a unique key for each row. Both the Course and
|
||
the Student columns make up the key. Grade is a nonkey column. What we must look for
|
||
is a dependency between one of the columns in the key and the other columns. In this case
|
||
there are none, so this table is in second normal form.
|
||
|
||
But suppose we added a column for class rooms. Since the Room column depends upon
|
||
the Course column. we would not be in second normal form. This is called a partial
|
||
dependency because columns are dependent on a partial key. that is. less than all of the
|
||
columns of the key.
|
||
|
||
Third Normal Form
|
||
|
||
Third normal form requires that we also eliminate any dependencies between nonkey
|
||
columns. These are called transitive dependencies.
|
||
|
||
Consider, for example, the room.size table:
|
||
|
||
Course Room Size
|
||
cs-101 DB-1 250
|
||
chem-1 HA-18 17
|
||
his-10 HA-18 17
|
||
art-la RB-8 23
|
||
econ-1 RB-8 23
|
||
|
||
Here the Size column depends on the Room column. To reach third normal form we must
|
||
make two tables: one called course.room, with the Course and Room columns; and the
|
||
other called room, with the Room and Size columns.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 90 / Buchseite 80 ====
|
||
80 Data-Base Design
|
||
|
||
Normalizing Example
|
||
|
||
Let's start with a simple universal table and normalize it step by step. Suppose we go to the
|
||
dean of the college to work out the college data base for grades. Since the dean does not
|
||
know about normalization, she lists all of the items she wants to keep track of, but our job
|
||
is to put them into tables. The universal table she builds might look like this:
|
||
|
||
Course Student Grade Teacher Title Child
|
||
|
||
chem-1 1 3 4 Assist. Sally, Mike, Joy
|
||
chem-1 2 2 1 Assist. Fred
|
||
|
||
chem-1 3 2 1 Assist.
|
||
|
||
cs-101 2 1 2 Prof. Fred
|
||
|
||
cs-101 4 4 2 Prof.
|
||
|
||
econ-1 iL 3 2 ~=Prof. Sally, Mike, Joy
|
||
econ-1 2 3 2 Prof. Fred
|
||
|
||
econ-1 3 2 2 Prof.
|
||
|
||
his-10 1 3 3 Assoc. Sally, Mike, Joy
|
||
|
||
Look at this unnormalized table and see if you can normalize it before we show you how.
|
||
|
||
First normalization requires that we get rid of the one-to-many relationship between
|
||
students and their children to remove multiple values in the Child column. We create a
|
||
new table for children of the students:
|
||
|
||
Student Child
|
||
1 Sally
|
||
1 Mike
|
||
1 Joy
|
||
2 Fred
|
||
|
||
We could add more columns about each child to this table as long as we are careful not to
|
||
include information about the student-parent which should be put into the student table.
|
||
We also remove the Child column from the big table. The command column accomplishes
|
||
this task:
|
||
|
||
column Course Student Grade Teacher Title < universe
|
||
This yields:
|
||
Course Student Grade Teacher Title
|
||
|
||
chem-1 1 3 1 Assist.
|
||
chem-1 2 2 1 Assist.
|
||
chem-1 3 2 “ F Assist.
|
||
cs-101 2 1 2 Prof,
|
||
cs-101 4 4 2 Prof.
|
||
econ-1 1 3 2 Prof.
|
||
econ-1 2 3 2 Prof.
|
||
econ-1 3 2 2 Prof.
|
||
his-10 1 3 3 Assoc,
|
||
|
||
For second normal form we have to realize that we have a multi-column key: Course and
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 91 / Buchseite 81 ====
|
||
Data-Base Design 81
|
||
|
||
Student, which uniquely determines each row. Let's look for dependencies between either
|
||
of these columns and the other columns. As you can see. Course determines Teacher. So.
|
||
let's use column to create a new course.teacher table:
|
||
|
||
column Course Teacher Title < universe > course.teacher
|
||
|
||
This table appears as follows:
|
||
|
||
Course Teacher Title
|
||
chem-1 1 Assist.
|
||
chem-1 a Assist.
|
||
chem-1 1 Assist.
|
||
cs-101 2 Prof.
|
||
cs-101 2 Prof.
|
||
econ-1 2 Prof.
|
||
econ-1 2 Prof.
|
||
econ-1 2 Prof.
|
||
his-10 3 Assoc,
|
||
|
||
And, then use column to create a table called grade:
|
||
|
||
column Course Student Grade < universe > grade
|
||
|
||
This yields:
|
||
|
||
Course
|
||
|
||
cs-101
|
||
cs-101
|
||
econ-1
|
||
econ-1
|
||
econ-1
|
||
his-10
|
||
|
||
Student
|
||
|
||
PWN ENWNHH
|
||
|
||
WBNwWWERHENNW
|
||
|
||
Note that there are many redundant rows in the course.teacher table. We can reduce the
|
||
table to unique rows by using the COHERENT uniq command to remove duplicate rows:
|
||
|
||
unig < course.teacher
|
||
|
||
This yields:
|
||
|
||
Course Teacher Title
|
||
chem-1 1 Assist.
|
||
es-101 2 Prof.
|
||
econ-1 2 Prof.
|
||
his-10 3 Assoc.
|
||
|
||
The grade table is now in second and third normal form, but the new course.teacher table
|
||
is only in second normal form. Note that Title depends upon Teacher. We need another
|
||
table; so we'll use column to create it, as follows:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 92 / Buchseite 82 ====
|
||
82 Data-Base Design
|
||
|
||
column Teacher Title < course.teacher | uniq > teacher
|
||
|
||
The new table, called teacher, contains the following:
|
||
|
||
Teacher Title
|
||
5 E Assist
|
||
2 Prof.
|
||
3 Assoc.
|
||
|
||
Now, we'll use column to check the contents of course.teacher:
|
||
column Course Teacher < course.teacher
|
||
|
||
This writes the following onto the screen:
|
||
|
||
Course Teacher
|
||
chem-1 1
|
||
cs-101 2
|
||
econ-1 2
|
||
his-10 3
|
||
|
||
So now the teacher and course.teacher tables are in third normal form. How many tables
|
||
do we have? What are their names? What columns are in each table? How would you
|
||
explain to the dean what you have done to her nice big table? Why have you done it?
|
||
|
||
Complex Queries with Joins
|
||
|
||
When data are distributed to many tables, how can we get the information we want? It is
|
||
easy to project columns and select rows from a single table and join two tables. But what if
|
||
the information we want is widely separated?
|
||
|
||
As an example, let us imagine that you are an instructor in a college and want a phone
|
||
book of all of your students, just in case you need to call to tell them that the class was
|
||
canceled or that the final exam date or room had changed. Suppose all you know is your
|
||
own name and the different tables in the data base:
|
||
|
||
Table of College Data Base Tables
|
||
|
||
Table Columns
|
||
|
||
teacher Teacher First Last Address City State Phone Title
|
||
teacher.course Teacher Course
|
||
|
||
course Course Credit Room Day Time Teacher
|
||
course.student Course Student
|
||
|
||
student Student First Last Year Phone
|
||
|
||
Such a phone book or listing can be produced with a single pipeline. First let's think
|
||
through the solution. Then we will build the one-line query.
|
||
|
||
You know your name, so you can find your ID number in the teacher file. With your
|
||
teacher ID number, you can get a table of all of your class ID numbers from the
|
||
teacher.course connector file. Then you can pick up the student ID numbers from the
|
||
course.student connector file. Finally, you can project the information you want about
|
||
each of your students.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 93 / Buchseite 83 ====
|
||
Data-Base Design 83
|
||
|
||
Pipeline Join
|
||
Now let's look at the pipeline. It has been written down the page to make it easier to read
|
||
|
||
and modify. When the Bourne and Korn shells sees the pipe symbol at the end of a line,
|
||
they know to continue to the next line because this line is not finished:
|
||
|
||
row ‘First == "Joy" && Last == "Xi" ‘ < teacher |
|
||
column Teacher |
|
||
|
||
tee tmpl |
|
||
|
||
jointable - teacher.course |
|
||
column Course |
|
||
|
||
sorttable |
|
||
|
||
tee tmp2 |
|
||
|
||
jointable - course.student |
|
||
column Student Course |
|
||
sorttable |
|
||
|
||
tee tmp3 |
|
||
|
||
jointable - student |
|
||
|
||
column Course Last First Phone |
|
||
sorttable > phonebook
|
||
|
||
This probably looks overwhelming, but don’t worry, we are going to go through each part.
|
||
First, let's look at the output so that we will know where we are going with all of this.
|
||
|
||
Course Last First Year Phone
|
||
cs-101 Dunce Boris 2 765-4321
|
||
cs-101 Early Mary 4 123-4567
|
||
econ-1 Early Mary 4 123-4567
|
||
econ-1 Farkel Freddy 3 123-1234
|
||
econ-1 Knott Why 1 123-7654
|
||
Note that the command
|
||
tee tmp
|
||
|
||
has been inserted in three places in the pipeline. The COHERENT tee command writes the
|
||
standard input to the standard output, but also write the stream of characters into the file
|
||
tmp. By looking at the tmp files, we have a peephole into the pipeline so that we can see how
|
||
the data look at each point. Therefore, we can see and discuss the data at three points in
|
||
the pipeline.
|
||
|
||
tmp1
|
||
|
||
Assuming your name is “Joy Xi", you can select the row in the teacher file in which the first
|
||
name, First, is “Joy” and the last name, Last, is “Xi". Then you can project the Teacher ID
|
||
number column only. column throws away the other columns. This is to reduce the
|
||
amount of data flowing through the pipe to speed up the execution. It also avoids conflicts
|
||
in the names of columns:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 94 / Buchseite 84 ====
|
||
84 Data-Base Design
|
||
|
||
row ‘First == "Joy" && Last == "Xi" ’ < teacher |
|
||
column Teacher |
|
||
tee tmpl1 |
|
||
|
||
Now let's see what the data look like by looking at the tmp] file:
|
||
|
||
Teacher
|
||
|
||
2
|
||
|
||
Here we have gotten the Teacher ID number in a little table that we can now use to find
|
||
more data.
|
||
|
||
tmp2
|
||
The next four lines join the single-line table above with the teacher.course table to pickup
|
||
|
||
the courses that “Joy Xi" teaches. Then only the Course column is projected. It must be
|
||
sorted for the next join:
|
||
|
||
jointable - teacher.course |
|
||
column Course |
|
||
|
||
sorttable |
|
||
|
||
tee tmp2 |
|
||
|
||
By taking a look at our data now, we see that “Joy Xi" teaches two courses:
|
||
|
||
Course
|
||
|
||
tmp3
|
||
|
||
Now we can join this two-row table to the course.student table to pick up the students in
|
||
her classes. This time we project not only their ID numbers but the courses because we
|
||
want that information carried on to the phone book. The Student column also must be
|
||
sorted for the next join. We have to tell the sorttable command that the Student column is
|
||
numeric, instead of string, to get a correct sort:
|
||
|
||
jointable - course.student |
|
||
column Student Course |
|
||
sorttable -n |
|
||
|
||
tee tmp3 |
|
||
|
||
Here is the output of these lines:
|
||
|
||
1 econ-1
|
||
2 cs-101
|
||
2 econ-1
|
||
3 econ-1
|
||
4 cs-101
|
||
|
||
Note that we have only the Student and the Course columns, and that the Student column
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 95 / Buchseite 85 ====
|
||
Data-Base Design 85
|
||
|
||
is correctly sorted.
|
||
|
||
Phone Book
|
||
|
||
The last lines join this table above with the student file to get the student information.
|
||
Then the columns we want for the phone book are projected. Note that we project the
|
||
Course column that was carried along as well as columns from the student table. We must
|
||
sort the new phone book by course so that the teacher can see all of the students in one
|
||
class:
|
||
|
||
jointable - student |
|
||
column Course Last First Phone |
|
||
sorttable > phonebook
|
||
|
||
Let's see the final output phone book again:
|
||
|
||
Course Last First Year Phone
|
||
|
||
cs-101 Dunce Boris 2 765-4321
|
||
cs-101 Early Mary 4 123-4567
|
||
econ-1 Early Mary 4 123-4567
|
||
econ-1 Farkel Freddy 3 123-1234
|
||
econ-1 Knott Why 1 123-7654
|
||
|
||
Note that we have done this in such a way that some students’ information is repeated if
|
||
they are taking more than one class from this teacher. Mary Early, in the table above, is an
|
||
example. We accept this repetition so that the teacher can call all of the students in a
|
||
particular class. If we had just a list of all the students, we would not know which student
|
||
was in what class. But you can change this example many different ways by changing the
|
||
column, sorttable, and jointable commands.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 96 / Buchseite 86 ====
|
||
86 Data-Base Design
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 97 / Buchseite 87 ====
|
||
Section 7:
|
||
|
||
Shell Programming
|
||
|
||
The great advantage of the COHERENT system is that most of the work is done for you.
|
||
Most data base systems create a new language that you must learn, but /rdb uses
|
||
COHERENT programs and the shell programming language. If you already know these
|
||
COHERENT tools, there is little more to learn. If you don’t know the COHERENT system, it
|
||
is much better to learn the general-purpose COHERENT system than a special language
|
||
that is only good for a single data base package. COHERENT tools as they are delivered on
|
||
your system can do much of the data base application. /rdb only extends the COHERENT
|
||
system by adding more than a hundred commands that will make data base handling easier
|
||
and faster.
|
||
|
||
Data-Base Programming in COHERENT Shell Language
|
||
|
||
It is the shell programming language that make this approach so easy and powerful. The
|
||
shell is the user interface to the COHERENT system. It prompts you for commands.
|
||
rewrites your command line to save you typing, and executes the programs you request. It
|
||
is extremely simple to learn. You start by putting commands that you would type at the
|
||
terminal, into files called shell programs. These files can be executed simply by typing their
|
||
names.
|
||
|
||
But the shell is also a powerful string-oriented programming language with control flow
|
||
statements like if. for. and while. You can mix procedural with nonprocedural statements.
|
||
|
||
Procedural programs are the traditional step-by-step instructions that tell the computer how
|
||
to do something. Nonprocedural statements simply tell the computer what to do. For
|
||
example, a traditional procedural program will tell the computer how to sort a file. A
|
||
nonprocedural statement in the COHERENT system would be
|
||
|
||
sort file
|
||
|
||
where file is the name of the file we want sorted. The COHERENT sort command knows
|
||
how to sort a file, so we get what we want with out worrying about details. If we had to
|
||
write the sort program, it would take ten to 100 lines of code, or more. Nonprocedural is
|
||
much easier and saves a lot of time. It is also much faster to fix. Options to the sort
|
||
program can reverse the sort. Editing a sort program is much trickier.
|
||
|
||
Of course. nonprocedural is best. but if a system is all nonprocedural. it has to anticipate
|
||
everything you will ever want to do! Most fourth-generation systems have this problem:
|
||
they give you a lot of functions, but lack procedural language statements to let you program
|
||
what they don't have. Third-generation languages let you program anything. but force you
|
||
to carefully code too many basic functions over and over. The COHERENT system gives you
|
||
a nice mix of predeveloped programs that cover all of the basic actions, and the shell
|
||
programming language to allow you to code more complex functions by building up basic
|
||
functions.
|
||
|
||
In the COHERENT environment, you are constantly in a process of automating your work.
|
||
First, you try out a simple program. Then call it, and other programs, from a higher-level
|
||
program. Soon you are able to do many things with simple keystrokes.
|
||
|
||
87
|
||
|
||
==== PDF-Seite 98 / Buchseite 88 ====
|
||
88 Shell Programming
|
||
|
||
There are a number of books on shell programming, in addition to the COHERENT
|
||
documentation. Before we discuss shell programming further. we will need some
|
||
COHERENT programs to build applications.
|
||
|
||
COHERENT Utilities
|
||
|
||
In addition to the /rdb commands, there are several COHERENT utilities that you will
|
||
probably need often. Your COHERENT documentation provides detailed descriptions of
|
||
these commands; we briefly describe some of their data base uses.
|
||
|
||
awk: Language to Produce Complex Reports
|
||
|
||
awk is the heart of several /rdb commands. awk provides the engine for the row, compute,
|
||
and validate commands. It can be used by itself to do powerful things to tables. For more
|
||
advanced applications, you must refer to the awk Lexicon entry and tutorial.
|
||
|
||
cat: Display a Table or List File
|
||
cat is used all the time to list out your tables.
|
||
|
||
echo: Repeat a Statement
|
||
|
||
This command repeats text. It lets you easily pass arguments to command and expand
|
||
environmental variables.
|
||
|
||
grep: Find All Rows That Contain a Given String
|
||
|
||
grep lets you search a table or any text file for a string of characters. If a match is found,
|
||
the line is printed. It is a primitive search, but easy to use.
|
||
|
||
od -c: Octal Dump All Bytes as Characters
|
||
|
||
od lets you see special characters and can be used to see if your tabs are in place. (The
|
||
/rdb see command is better for this purpose.)
|
||
|
||
sed: Stream Editor to Edit File in a Pipe
|
||
|
||
sed is a very powerful program for editing your tables in a pipe stream. Many of the /rdb
|
||
shell programs use it. You can perform almost any editor command with it.
|
||
|
||
sh: COHERENT Shell Programming Language
|
||
|
||
sh is the COHERENT shell program that interfaces to the user. It prompts with a dollar
|
||
sign (8) or other prompt, then reads the commands that the user types. It is a powerful
|
||
string-oriented programming language. You can create any complex application with it and
|
||
the COHERENT and /rdb commands.
|
||
|
||
ksh is the other COHERENT shell programming language. It is, for the most part, a
|
||
superset of sh. It differs from sh mainly in that it lets you recall, edit, and resubmit
|
||
command that you had typed earlier, using MicroEMACS-style editing commands. See the
|
||
COHERENT manual's Lexicon entries on sh and ksh for descriptions of each language, and
|
||
how they differ.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 99 / Buchseite 89 ====
|
||
Shell Programming 89
|
||
|
||
spell: Check Spelling in a Table or List File
|
||
|
||
You may find this quite useful for checking spelling in a file. It is also a good example of the
|
||
power of shell programming.
|
||
|
||
tail: Display Bottom Rows of a Table or List File
|
||
tail outputs the end ofa file. You can use it to “behead” a table. Consider table mailtable:
|
||
|
||
for the same purpose.
|
||
Number Name Company Phone
|
||
|
||
1 Ronald McDonald McDonald‘s (111) 222-3333
|
||
2 Chiquita Banana United Brands 1234
|
||
|
||
The command
|
||
|
||
tail +3 mailtable
|
||
|
||
yields:
|
||
|
||
1 Ronald McDonald McDonald’s (111) 222-3333
|
||
2 Chiquita Banana United Brands 1234
|
||
|
||
As you can see, the first two “head” lines of the table have been thrown away.
|
||
There is also the /rdb command headoff
|
||
|
||
we: Word Count
|
||
|
||
This command counts the characters, words, and lines in a file.
|
||
|
||
Text Editor to Enter and Update Files
|
||
|
||
A text editor is important to your work, because you will use it to set up tables and lists and
|
||
to write your shell program applications. COHERENT comes with three interactive text
|
||
editors:
|
||
|
||
ed This is a powerful, line-oriented editor. This editor is best for making mass
|
||
transformations of a file, because you can use normal expressions to tell it what to
|
||
do. ed is also useful in editing files that are too large for a screen-oriented editor to
|
||
handle, at least in the 80286 edition of COHERENT.
|
||
|
||
me This is the MicroEMACS editor. It is the preferred editor of most COHERENT users.
|
||
As its name implies, it is a smaller, more efficient version of Richard Stallman’s
|
||
famous EMACS editor. With it, you can display multiple files in multiple windows
|
||
upon your screen, move text from one file or window to another. Unlike ed,
|
||
MicroEMACS lets you address the text to be edited by moving the cursor to it —
|
||
hence, it is considered to be a “screen-oriented” editor.
|
||
|
||
vi This is the COHERENT implementation of the UNIX standard editor. It has features
|
||
of both ed and MicroEMACS, plus many features of its own.
|
||
|
||
Each editor is summarized at length in the COHERENT Lexicon. The COHERENT manual
|
||
also contains tutorials for ed and me. Any of these three editors will do the job for you;
|
||
which you select is largely up to your personal preference. Each editor has its strengths
|
||
and weaknesses; an editing job that takes hours with one editor might take only minutes
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 100 / Buchseite 90 ====
|
||
90 Shell Programming
|
||
|
||
with another. You would do well to learn at least the riduments of each editor, so you can
|
||
select the right editor for a given editing job.
|
||
|
||
Reading and Writing Data Base Files
|
||
|
||
When you write programs, you have to open files. In the COHERENT environment, files
|
||
usually come to the program from standard-in and output is sent to standard-out. But
|
||
sometimes you have a shell program that is talking to the user at the terminal through the
|
||
standard-in and -out, but has to open one or more files for reading and writing. This is
|
||
done with the exec command. This code opens /filein for input (read) and assigns the file
|
||
descriptor 3, fileout is opened for output (write) and assigned file descriptor 4. Then
|
||
programs can use those file descriptors with the <&3 and >&4 conventions:
|
||
|
||
exec 3< filein
|
||
exec 4> fileout
|
||
cat <&3 >&4
|
||
|
||
The COHERENT shell's read command cannot have its input redirected to a file other than
|
||
standard-in, except by a trick:
|
||
|
||
exec 0< inventory
|
||
read HEAD
|
||
|
||
Here, we have set the environmental variable HEAD to contain:
|
||
Item Amount Cost Value Description
|
||
|
||
In a loop you can read a whole file line by line. The while statement is a control statement
|
||
that executes the lines within the do and done until read tries to read the end-of-file and
|
||
returns a status code indicating false.
|
||
|
||
exec 0< inventory
|
||
while read HEAD
|
||
do
|
||
|
||
echo “$HEAD"
|
||
done
|
||
|
||
This yields:
|
||
Item Amount Cost Value Description
|
||
|
||
4 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
|
||
3 5 80 400 clamps
|
||
|
||
4 23 19 437 plates
|
||
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 101 / Buchseite 91 ====
|
||
Shell Programming 91
|
||
|
||
Parsing Rows
|
||
|
||
You can use the set command to parse strings in the shell. For example, if you want to get
|
||
at any field in a row you can read the row into a shell variable and set the words in the row
|
||
to the shell positional arguments $1 and $2:
|
||
|
||
exec 0< inventory
|
||
|
||
read HEAD
|
||
|
||
set $HEAD
|
||
|
||
echo “The first field is $1 and the fifth field is $5."
|
||
|
||
The final command, echo, displays its first and fifth arguments. This prints the following:
|
||
|
||
The first field is Item and the fifth field is Description.
|
||
|
||
Tables to Shell Variables
|
||
|
||
It would be very nice if we could use the column names from a table to refer to the column
|
||
values in a shell program. Often people assume they have to walk through the row with for
|
||
and, perhaps, shift commands. This slow method is not necessary. Here is a neat trick for
|
||
using column heads as variables in shell programs.
|
||
|
||
Consider, to begin, table inventory:
|
||
|
||
Item
|
||
|
||
NOUPWNHHE
|
||
|
||
Amount Cost Value Description
|
||
|
||
3 50 150 rubber gloves
|
||
100 5 500 test tubes
|
||
§ 80 400 clamps
|
||
23 19 437 plates
|
||
99 24 2376 cleaning cloth
|
||
89 147 13083 bunsen burners
|
||
5 175 875 scales
|
||
|
||
Now consider the shell script onhand:
|
||
|
||
USAGE=’usage: onhand Item < inventory’
|
||
|
||
FOUND=0
|
||
NOFOUND=1
|
||
read HEAD
|
||
read DASH
|
||
while read $HEAD
|
||
do
|
||
if test "$Item" -eq "$1"
|
||
then
|
||
echo We have $Amount $Description on hand.
|
||
exit $FOUND
|
||
i 9
|
||
|
||
done
|
||
exit $NOFOUND
|
||
|
||
Now, the command
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 102 / Buchseite 92 ====
|
||
92 Shell Programming
|
||
|
||
onhand 2 < inventory
|
||
yields:
|
||
|
||
We have 100 test tubes on hand.
|
||
Now, let's walk through onhand and see just what it does.
|
||
The first three lines
|
||
|
||
USAGE=’usage: onhand Item < inventory’
|
||
FOUND=0
|
||
NOFOUND=1
|
||
|
||
set some environmental variables that are used for printing an error message should a
|
||
mistake occur,
|
||
|
||
Next, the line
|
||
|
||
read HEAD
|
||
reads the first line of inventory into a shell variable called HEAD.
|
||
The next line
|
||
|
||
read DASH
|
||
|
||
reads the dash line into an environmental variable called DASH. We want to throw away the
|
||
dash line, and this is an easy way to do it.
|
||
|
||
Next comes the while loop:
|
||
while read $HEAD
|
||
|
||
do
|
||
if test "$Item" -eq "$1"
|
||
then
|
||
echo We have $Amount $Description on hand.
|
||
exit $FOUND
|
||
fi
|
||
done
|
||
|
||
Look carefully at the read statement. It examines HEAD, which the shell expands into the
|
||
list of column names, before read is called. So read really sees all of the column names as
|
||
arguments:
|
||
|
||
read Item Amount Cost Value Description
|
||
|
||
read assigns the first word it reads from standard-in to Item, then the next to Amount, and
|
||
soon. Therefore, it has automatically assigned the column values to the column names for
|
||
us and we can use them in the shell program with 8 in front.
|
||
|
||
The test and echo commands both use the variables that hold the values from the current
|
||
row. Let's see this with the shell execution trace option -x turned on:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 103 / Buchseite 93 ====
|
||
Shell Programming 93
|
||
|
||
+ read HEAD
|
||
|
||
+ read DASH
|
||
|
||
+ read Item Amount Cost Value Description
|
||
+ test 1 -eq 2
|
||
|
||
+ read Item Amount Cost Value Description
|
||
+ test 2 -eq 2
|
||
|
||
+ echo We have 100 test tubes on hand.
|
||
|
||
We have 100 test tubes on hand.
|
||
|
||
This lets you see how the column names and values are rewritten as each row is read,
|
||
tested, and processed.
|
||
|
||
Lists to Shell Variables
|
||
|
||
Here is an example of how to get records from a list formatted file and make each column
|
||
name-value pair a shell variable=value pair. It uses the /rdb program listtosh to convert
|
||
the list record to shell format. Consider the list maillist:
|
||
|
||
Number 1
|
||
|
||
Name Ronald McDonald
|
||
Company McDonald's
|
||
Street 123 Mac Attack
|
||
city Menphis
|
||
|
||
State TENN
|
||
|
||
ZIP 30000
|
||
|
||
Phone (111) 222-3333
|
||
|
||
The command
|
||
|
||
listtosh < mail.list
|
||
|
||
yields:
|
||
|
||
Number='1’
|
||
|
||
Name=’Ronald McDonald’
|
||
Company=’McDonald\'s’
|
||
Street='123 Mac Attack’
|
||
City='’Menphis’
|
||
State=’TENN’
|
||
ZIP=’30000’
|
||
Phone=’(111) 222-3333’
|
||
|
||
See the tabs converted to equal signs ‘=" and the data protected absolutely by apostrophes
|
||
(). Also note that each apostrophe within the data is protected with a backslash ‘\'. This is
|
||
the format for the shell variable=value assignments. This program can be executed in a
|
||
shell program and the variable=value pair will become known to the program. The
|
||
command:
|
||
|
||
column Name Phone < mail.list | listtosh
|
||
yields:
|
||
Name=’Ronald McDonald’ Phone=’(111) 222-3333’
|
||
|
||
This one line output from the command substitution is exactly the format the shell uses to
|
||
assign values to its variables. As you can see, the shell can read multiple assignments on
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 104 / Buchseite 94 ====
|
||
94 Shell Programming
|
||
|
||
one line. The apostrophes allow anything to be in the data without being expanded by the
|
||
shell. In this example, we projected only Name and Phone, to keep from having a long line
|
||
and to show that we can use any command to get the variables we want.
|
||
|
||
In the next example, eval is used to rescan and assign the line:
|
||
eval ‘column Name Phone < mail.list | listtosh’
|
||
echo “$Name’s phone number is $Phone."
|
||
|
||
This yields:
|
||
|
||
Ronald McDonald’s phone number is (111) 222-3333.
|
||
|
||
Now we can use the values of the variable in a shell program. This example contains an
|
||
echo statement to see that the variable had been correctly assigned to the current shell.
|
||
and not to some subshell.
|
||
|
||
The next example is more complex. A table is searched for a record and converted to list
|
||
and then used in the shell program:
|
||
|
||
echo ‘row ‘Item == 3' < inventory | tabletolist | listtosh’
|
||
eval ‘row ‘Item == 3’ < inventory | tabletolist | listtosh’
|
||
echo "We have $Amount $Description."
|
||
|
||
This yields:
|
||
|
||
Item=’3' Amount=’5' Cost=’80' Value='400' Description=’clamps’
|
||
We have 5 clamps.
|
||
|
||
Report Writing
|
||
|
||
UNIX World magazine printed two articles by Alan Winston about fourth-generation
|
||
programming languages (July 1986 and April 1987). Several competing companies were
|
||
invited to produce a sample report using their 4GL systems. Most of these languages
|
||
looked more like COBOL or RPG. Here are two ways of producing the sample report with
|
||
the COHERENT shell and /rdb.
|
||
|
||
The first example is a simple default report (which we think looks better than the report
|
||
format required in the article):
|
||
|
||
number fname lname code hours rate total
|
||
1 John Wilson 2 3 75
|
||
7 John Wilson 2 4 75
|
||
1 yf
|
||
2 Fred Jackson 1 4 85 340
|
||
2 Fred Jackson 2 5 85 425
|
||
2 9 765
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 105 / Buchseite 95 ====
|
||
Shell Programming 95
|
||
|
||
3 Anne Rowan 2 5 75 375
|
||
3 Anne Rowan 1 6 75 450
|
||
3 11 825
|
||
|
||
2115
|
||
|
||
Following is the shell script that produces this default report. Note that it only takes only
|
||
11 lines of simple, readable code. Actually, it could be written in two lines, but we put each
|
||
command on a separate line. This example does not require counting columns or
|
||
characters. There is no “line-at-a-time” processing, as with the other so-called 4GLs —
|
||
rather, whole files are processed at once:
|
||
|
||
jointable hours employee |
|
||
sorttable code |
|
||
jointable -j1 code ~j2 number - task |
|
||
sorttable number |
|
||
column number fname lname code hours rate total |
|
||
compute ‘total = hours * rate’ |
|
||
justify > tmp
|
||
|
||
subtotal -l1 number hours total < tmp
|
||
|
||
total total < tmp |
|
||
justify |
|
||
tail -1
|
||
|
||
The data used in the UNIX World samples were not included in the articles, primarily
|
||
because their format is virtually unprintable. /rdb data are flat ASCII files. Table hours is
|
||
as follows:
|
||
|
||
number hours code
|
||
|
||
ane ew
|
||
NNENN
|
||
|
||
a
|
||
»
|
||
|
||
number fname lname rate
|
||
1 John Wilson 75
|
||
2 Fred Jackson 85
|
||
3 Anne Rowan 75
|
||
|
||
And table task is as follows:
|
||
|
||
number name
|
||
|
||
1 unix/world
|
||
2 \rdb
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 106 / Buchseite 96 ====
|
||
96 Shell Programming
|
||
|
||
Here is the exact report format required in the UNIXWorld articles of July 1986:
|
||
|
||
number Employee Name code hours rate total
|
||
1 John Wilson 2 3.00 75.00 225.00
|
||
a 2 4.00 75.00 300.00
|
||
* Employee Total 7.00 525.00
|
||
|
||
2 Fred Jackson 1 4.00 85.00 340.00
|
||
2 2 5.00 85.00 425.00
|
||
* Employee Total 9.00 765.00
|
||
|
||
3 Anne Rowan 2 5.00 75.00 375.00
|
||
3 4 6.00 75.00 450.00
|
||
* Employee Total 11.00 825.00
|
||
|
||
** Report Total 2115.00
|
||
|
||
And here is the COHERENT shell and /rdb program that produces the exact format:
|
||
|
||
jointable hours employee |
|
||
|
||
sorttable code |
|
||
|
||
jointable -j1 code -j2 number - task |
|
||
|
||
sorttable number |
|
||
|
||
column number hours code fname lname rate name total |
|
||
|
||
compute ‘total = hours * rate; name = sprintf("%s %s",fname,lname)’ |
|
||
column number name code hours rate total > tmp
|
||
|
||
compute ‘if (name == prev) name = ""; prev = name;\
|
||
|
||
hours = sprintf("%4.2f",hours); rate = sprintf("%6.2f",rate);\
|
||
total = sprintf("%7.2f",total)’ < tmp |
|
||
|
||
subtotal -l number hours total |
|
||
|
||
compute ‘if (code ~ / / && code !~ /-/) code = "* Employee Total";\
|
||
if (code ~ / / && code !~ /~/) number = ""’ > tmpl
|
||
|
||
rename name "Employee Name" < tmp1 |
|
||
|
||
justify -r number hours rate total -l "Employee Name" -c code |
|
||
sed "/---/d" | sed "s/*/ /" | sed "s/rate/ rate/" |
|
||
|
||
sed "s/total / total/"
|
||
|
||
TOTAL=‘column total < tmp |\
|
||
|
||
total | compute ‘total = sprintf("%10.2f",total)’| headoff’
|
||
echo " \
|
||
|
||
** Report Total $TOTAL"
|
||
|
||
This is still only 22 lines. The powers of the COHERENT shell, awk, and sed programs are
|
||
used for string and arithmetic processing. The user only needs to know COHERENT tools,
|
||
not yet another language. If you know COHERENT tools, you understand this; and if you
|
||
do not, learning them has much greater value than learning yet another special
|
||
programming language from a single vendor. As COHERENT and MS-DOS/UNIX systems
|
||
become the standard, you can use your COHERENT skills on almost all computers.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 107 / Buchseite 97 ====
|
||
Section 8:
|
||
|
||
Shell Menus
|
||
|
||
When setting up software applications, it can be important to provide menus to the user.
|
||
These tell the users what options are available. and make it easy for them to choose the
|
||
ones they want. As more functions are added to the system, they can also be added to the
|
||
menus. In this chapter a simple shell program menu is discussed.
|
||
|
||
Example Shell Menu Program
|
||
|
||
A simple way to create menus in COHERENT is with a shell script. The advantage of using
|
||
shell programming is that it is so easy and you can do anything with it. A sample menu
|
||
program is included with /rdb. You can copy it into your own directory and edit it to be one
|
||
or more menus for your system, For details see the menu manual page.
|
||
|
||
The menu program is in two parts. The first half of the menu simply paints the menu
|
||
selections on the CRT terminal. It is a simple COHERENT cat or echo command:
|
||
|
||
cat <<SCREEN
|
||
$CLEAR COHERENT MENU
|
||
|
||
Number Name
|
||
|
||
i) exit leave menu or return to higher menu
|
||
i Menu goto another local menu (if any)
|
||
2 sh get unix shell
|
||
|
||
3 vi edit a file
|
||
|
||
4 mail read mail
|
||
|
||
5 send send mail to someone
|
||
|
||
6 cal see your calendar
|
||
|
||
7 who see who is on the system
|
||
|
||
8 1s list the files in this directory
|
||
9 cat display a file on the screen
|
||
|
||
10 rdb display rdb commands
|
||
|
||
Please enter a number or name for the action you wish or DEL to exit:
|
||
SCREEN
|
||
|
||
The cat command shown uses the here file feature of the shell: all of the text from the
|
||
<<SCREEN to the line that consists of only SCREEN is sent to the standard input of the cat
|
||
command. cat sends its output to your terminal. So the text between the two SCREEN
|
||
lines is displayed on your screen.
|
||
|
||
This lets you edit any menu you wish. The one shown is only one example. Use your text
|
||
editor to set up any menu format you desire. Whatever you type will be displayed on the
|
||
user's terminal screen.
|
||
|
||
97
|
||
|
||
==== PDF-Seite 108 / Buchseite 98 ====
|
||
98 Shell Menus
|
||
|
||
case Actions
|
||
|
||
Whatever the user types is assigned to the shell variable ANSWER. (After the first word of
|
||
the reply, any more words are assigned to the shell variable COMMENT).
|
||
|
||
read ANSWER COMMENT
|
||
case $ANSWER in
|
||
|
||
O|exit) exit 0 ;;
|
||
1|Menu) Menu ;;
|
||
2|sh) sh ;;
|
||
|
||
3|vi)
|
||
|
||
echo ‘Which file or files do you wish to edit’
|
||
read ANSWER COMMENT
|
||
vi $ANSWER $COMMENT
|
||
4|mail) mail ;;
|
||
5| send)
|
||
echo ‘Please enter login name of person to send mail to’
|
||
read ANSWER COMMENT
|
||
echo ‘Type you letter, and end by typing Ctrl-d’
|
||
mail $ANSWER
|
||
6|cal) (cd ;
|
||
7|who) who ;;
|
||
8|ls) ls 3;
|
||
9|cat)
|
||
echo ‘Please enter the name of the file you wish to see’
|
||
read ANSWER COMMENT
|
||
|
||
calendar) ;;
|
||
|
||
cat $ANSWER
|
||
ae
|
||
10|rdb) menu.rdb ;;
|
||
*) echo ‘Sorry, but that number or name is not recognized.’ ;;
|
||
|
||
esac
|
||
|
||
After the user's answer is read in, the shell case statement is used to match the answer to a
|
||
number of possible cases. If the user types a number 8 or Is, then the Is command is
|
||
executed. This sample gives the user the choice of two ways to indicate a menu selection:
|
||
numbers or short mnemonic string names.
|
||
|
||
After the case pattern, you can type any shell command or call any shell program, or any
|
||
combination of both. This gives you complete power to do anything, as a result of a user's
|
||
choice. In the previous examples, you can see how to simply execute a command, invoke
|
||
another menu, ask for more information and use it in a command, and so on. The *) case is
|
||
selected if the user does not type any of the patterns previously listed. This gives an error
|
||
message.
|
||
|
||
To make this system work. two commands are needed. A clear command clears the screen
|
||
so that the form can be written on it and the cursor command moves the cursor to each
|
||
field of the screen.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 109 / Buchseite 99 ====
|
||
Shell Menus 99
|
||
|
||
termput and tput Commands
|
||
|
||
There are many CRT terminals with different capabilities and commands. Terminal
|
||
capabilities are described in the termcap file, which contain capability descriptions for a
|
||
number of commonly used terminals. You only need to find out what it calls your terminal
|
||
and assign that name to the sheli variable TERM. (Be sure to also export TERM). To pick
|
||
up the command string for a terminal capability /rdb provides the termput command. It
|
||
searches for the terminal name you assigned to TERM and then for the capability you
|
||
indicate.
|
||
|
||
clear Command
|
||
|
||
The clear command clears the screen. To speed up clearing the screen, assign the clear
|
||
command sequence to the shell variable CLEAR. Then you can use SCLEAR in echo and
|
||
cat <<HERE statements. This is ten to a hundred times faster because it does not require
|
||
that you look up the sequence in a file first:
|
||
|
||
CLEAR=‘termput cl’ # /rdb command
|
||
export CLEAR
|
||
echo $CLEAR
|
||
|
||
cursor Command
|
||
|
||
For the cursor command to work correctly, you must set up a shell variable called
|
||
CURSOR:
|
||
|
||
CURSOR=‘termput cm’
|
||
CURSOR=‘tput cup’
|
||
export CURSOR
|
||
cursor 20 40
|
||
|
||
The cursor command moves the cursor to line (row) 20, character (column) 40 on the
|
||
screen. It uses the sequence in the CURSOR variable.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 110 / Buchseite 100 ====
|
||
100 Shell Menus
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 111 / Buchseite 101 ====
|
||
Section 9:
|
||
Tables and Forms
|
||
|
||
Simple forms can be used to for data entry and to display data on CRT screens. The two
|
||
can be mixed with a form in which some fields are filled in and the data from the data base
|
||
is written into the remaining form fields. /rdb comes with several forms systems: ve,
|
||
described earlier, and a shell level forms system, described here. ve was designed to make
|
||
creating and entering data into /rdb data bases easy, using a vi-style interface. The screen
|
||
program, on the other hand, can be a more general-purpose application development tool
|
||
that can be customized for any specific application. It's an example of a program generating
|
||
a program.
|
||
|
||
To make the shell-level system work, you need the clear and cursor commands, described
|
||
in the previous chapter.
|
||
|
||
Building a Screen Form
|
||
|
||
You can write a shell script that paints a screen and accepts input. You can clear the
|
||
screen and use the cursor command to move to any location. There you can use the echo
|
||
or cat command to display whatever you wish. You can use the read command to read in
|
||
anything the user types and assign it to a shell variable. You can take the users
|
||
information and look up data in the data base, using the database query commands, and
|
||
display it anywhere on the screen. The update,inv command found in the SRDB/lib
|
||
directory is an example of this.
|
||
|
||
The screen program uses a screen definition form, which you create with any text editor
|
||
(just like the /rdb report program form):
|
||
|
||
Makeapile, Inc. Inventory Update <!date!l>
|
||
Item Number: <Item>
|
||
|
||
Item Cost Value Description
|
||
|
||
<Item> <Cost> <Value> <Description>
|
||
|
||
Amount Onhand: <Amount>
|
||
|
||
Then you input that form into the screen program:
|
||
screen < inv.f > inv.s
|
||
|
||
This yields:
|
||
|
||
101
|
||
|
||
==== PDF-Seite 112 / Buchseite 102 ====
|
||
102 Tables and Forms
|
||
|
||
: paint crt screen
|
||
exec 3>&1 1>&2
|
||
cat <<SCREEN
|
||
|
||
${CLEAR}Makeapile, Inc. Inventory Update
|
||
Item Number:
|
||
Item Cost Value Description
|
||
|
||
Amount Onhand:
|
||
SCREEN
|
||
|
||
+ read user input
|
||
cursor 0 56 ; date;
|
||
|
||
cursor 2 13 ; read Item;
|
||
cursor 6 O ; read Item;
|
||
cursor 6 12 ; read Cost;
|
||
cursor 6 23 ; read Value;
|
||
cursor 6 34 ; read Description;
|
||
cursor 8 15 ; read Amount;
|
||
|
||
t output table head
|
||
|
||
exec 1>&3
|
||
echo “Item Item Cost Value Description Amount"
|
||
echo "---- ---- ewe eee ewww ee eeeee ++ -
|
||
|
||
t append row
|
||
echo “$Item $Item $Cost $Value $Description $Amount"
|
||
|
||
The output is a shell program that will paint the screen, read the user's input, and output a
|
||
table of the user's responses. This shell program is simple, but you can edit it to do any
|
||
advanced operation you like.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 113 / Buchseite 103 ====
|
||
Section 10:
|
||
Fast-Access Methods
|
||
|
||
Fast-access methods allow you to get rows from a table or list file faster than sequentially
|
||
reading the file. This is very important for larger data bases. Where sequentially reading a
|
||
huge file would take minutes, the right fast-access method might take only a few seconds to
|
||
find the records you want. Traditionally, these methods were very important to data-base
|
||
management systems. For very large data bases, they will continue to be important. But
|
||
one or a few users on a microprocessor with small to medium-sized tables will seldom need
|
||
|
||
these speedups.
|
||
Appropriate Use
|
||
|
||
It is important to point out that these methods are not always faster and usually require
|
||
significant time to set up. They are almost never justified unless the file is large (more than
|
||
1,000 rows), and the extra time to index or sort the table is worthwhile.
|
||
|
||
The command row finds rows that match complex logical conditions and regular expression
|
||
(string patterns). But these fast-access methods require that the key value be expressed
|
||
more specifically. No greater than, less than, or string pattern matches: only equals, and
|
||
partial initial matches (for example, the first few letters of a key).
|
||
|
||
We've implemented five fast-access methods: sequential, record, inverted. binary, and hash.
|
||
/rdb has two commands that use these methods: index and search.
|
||
|
||
The index and search Commands
|
||
|
||
We will use a two-row table to show the index and search commands. Here is a mailtable:
|
||
|
||
Number Name Company Phone
|
||
|
||
a Ronald McDonald McDonald’s (111) 222-3333
|
||
2 Chiquita Banana United Brands 1234
|
||
|
||
The hash method is often the fastest, so let's use it as an example.
|
||
index -mh mailtable Name
|
||
|
||
The -m means method, and the h specifies hash. The index command builds a hash
|
||
secondary index table. You can see it, if you are curious, by listing out the table name
|
||
followed by the -h secondary index extension; for example, mailtable.h:
|
||
|
||
Offset
|
||
|
||
104
|
||
0
|
||
|
||
Each of the names in the Names column of the mailtable was hashed into row 4 (104) or 2
|
||
(156). The offset in the hash table (the nonzero numbers) is the location (in bytes) in the
|
||
|
||
103
|
||
|
||
==== PDF-Seite 114 / Buchseite 104 ====
|
||
104 Fast-Access Methods
|
||
|
||
main file, of the row with that key value.
|
||
|
||
Searching
|
||
|
||
The search command allows you to search for one or more rows in the table in four
|
||
different ways. You can input a key two ways, and you can input a table of keys two ways.
|
||
|
||
Interactive
|
||
|
||
Now you can search the mailtable by name in an interactive way:
|
||
search -mh mailtable Name
|
||
|
||
The search command first prints out the table head line
|
||
|
||
Number Name Company Phone
|
||
|
||
then waits for you to type in a key value. In this case, if you type
|
||
Ronald McDonald
|
||
search prints the following from maillist:
|
||
4, Ronald McDonald McDonald’s (111) 222-3333
|
||
|
||
After you type the name and hit the return key. the row will print almost immediately, even
|
||
if the file is huge. You may continue to type keys. When you are finished, type <ctrl-D>.
|
||
|
||
Pipe Key
|
||
|
||
The search command can also be used in a pipe. You can input a table or list of keys
|
||
through a pipe and the search command will output a table or list of rows which match
|
||
your input keys. This becomes a fast join. with keys coming in and a table of rows coming
|
||
out. For example, the command
|
||
|
||
echo "Ronald McDonald"| search -mh mailtable Name
|
||
|
||
yields
|
||
Number Name Company Phone
|
||
|
||
1 Ronald McDonald McDonald’s (111) 222-3333
|
||
File Input
|
||
|
||
In addition to sending a single key to search, you can also send a whole table of keys.
|
||
search will look up each key and output a whole table of matching rows. It is like a high
|
||
speed join; keys in, records out.
|
||
|
||
Here we have our name keys in a table called name:
|
||
|
||
Name
|
||
|
||
Ronald McDonald
|
||
Chiquita Banana
|
||
|
||
The following command directs it to the standard input of the search command and gets
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 115 / Buchseite 105 ====
|
||
Fast-Access Methods 105
|
||
|
||
the matching records out.
|
||
|
||
search -mh mailtable < name
|
||
|
||
This yields:
|
||
Number Name Company Phone
|
||
£ Ronald McDonald McDonald's (111) 222-3333
|
||
|
||
2 Chiquita Banana United Brands 1234
|
||
|
||
Note that you do not have to tell the search command the name of the column to search on,
|
||
if you send it a table with the column name, because search can pick up the column name
|
||
from that input table.
|
||
|
||
File Input by Pipe
|
||
|
||
You can also put the search program in a pipeline and it will send to its right a table of
|
||
rows that match the table of keys coming from its left. In other words, keys in. matching
|
||
records out.
|
||
|
||
As an example, consider again the table name:
|
||
|
||
Ronald McDonald
|
||
Chiquita Banana
|
||
|
||
The command
|
||
cat name | search -mh mailtable
|
||
writes the following to the standard output:
|
||
|
||
Number Name Company Phone
|
||
|
||
1 Ronald McDonald McDonald’s (111) 222-3333
|
||
2 Chiquita Banana United Brands 1234
|
||
|
||
The cat command simulates any program or pipeline that produces a table of keys.
|
||
including other search commands.
|
||
Multi-Rows, Multi-Columns, and Multi-Keys
|
||
|
||
The search command will produce multiple rows, if more than one row matches the key.
|
||
You can have multi-column keys consisting of more than one column. You can also send
|
||
more than one key, multi-keys, to search and it will output all matching rows.
|
||
|
||
Methods of Searching
|
||
|
||
The five different fast access methods each have their own advantages and disadvantages.
|
||
It is an art and a science to figure out which to use in a given situation, or whether to use
|
||
them at all.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 116 / Buchseite 106 ====
|
||
106 Fast-Access Methods
|
||
|
||
Sequential
|
||
|
||
Sequential is the simplest and slowest method. It is hardly a fast access method at all. but
|
||
is included for completeness. This method simply looks at every record in the table for a
|
||
match. With a big file, this will take a long time.
|
||
|
||
When might you use it? It is better than grep because a sequential search will look at only
|
||
a single column for a match, instead of the whole row. Thus it avoids matching strings in
|
||
the wrong columns of the row.
|
||
|
||
Also, use the sequential method to time how fast it takes. You will often be surprised that
|
||
this method is fast enough for your system. If it is fast enough, use it since it requires no
|
||
indexing or overhead to use. The table can be in any order and can be updated randomly.
|
||
|
||
Record
|
||
|
||
One problem with variable-length records is that there is no simple computation of where a
|
||
row such as number 7 is. Without this method, we would have to sequentially search the
|
||
table, counting records, until we came to the one we wanted. On the average we would have
|
||
to search half the file. When we index with this method, the index program runs through
|
||
the whole file and builds a secondary file which contains the offsets to each row. The
|
||
secondary index table is named by adding a .r to the end of the table name. It contains
|
||
fixed length rows so that the record number can be computed. At that address is the offset
|
||
of the corresponding record in the data-base table. For example, consider the following
|
||
|
||
mailtable:
|
||
Number Name Company Phone
|
||
1 Ronald McDonald McDonald’s (111) 222-3333
|
||
|
||
2 Chiquita Banana United Brands 1234
|
||
The command
|
||
index -mr mailtable
|
||
produces index table mailtable.r, which appears as follows:
|
||
Offset
|
||
|
||
Note that edch of the offsets in the secondary index table mailtable.r is the byte address of
|
||
that row in the main mailtable table.
|
||
|
||
Binary
|
||
|
||
The binary method requires that the table be sorted on the key columns. With this method.
|
||
the index command simply sorts the table. The search command can find the desired row
|
||
by first looking at a row in the middle of the table. It can use the COHERENT system call
|
||
seek() for fast access to any byte in the file. search compares the key value of that center
|
||
row with the key it is looking for. If the row’s key is too high, it jumps to the one-quarter
|
||
point in the file, if too low, to the three-quarter point in the file. Each probe cuts the file in
|
||
half so that the record can be found quickly.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 117 / Buchseite 107 ====
|
||
Fast-Access Methods 107
|
||
|
||
If there are a thousand records in the table, only ten probes are needed to find the record
|
||
you wish. One million records require only 20 probes. A billion records need only 30. This
|
||
is called log n search time, where n is the number of records in the file and the log to the
|
||
base of 2 is the number of probes needed to find a record. The sorting takes n log n time
|
||
with the fastest sort routines.
|
||
|
||
To prepare mailtable for this type of search, use the command:
|
||
index -mb mailtable Name
|
||
mailtable now looks like:
|
||
|
||
Number Name Company Phone
|
||
2 Chiquita Banana United Brands 1234
|
||
A. Ronald McDonald McDonald’s (111) 222-3333
|
||
|
||
Note that the Name column is now sorted so that the binary search will work. This is a
|
||
good method when you have to keep the file in sorted order anyway. Then your sorting pays
|
||
off twice. It is a painful method, however, if you are adding and deleting records often and
|
||
have to resort often.
|
||
|
||
Hash
|
||
|
||
The hash method takes the key and performs a mathematical operation on it that converts
|
||
it into a single number. Each ASCII character in the key is added together and modulo-ed
|
||
with the size of the hash table to produce a number that is its location in the hash table.
|
||
That number is an index into a secondary hash table. At that location should be the offset
|
||
to the record in the main table. The row at that offset in the main table is checked to see if
|
||
its key column(s) match the key we are looking for. If it is, we have found our record.
|
||
|
||
It might not match because more than one key may hash to the same number by accident.
|
||
If it does not match, the next offset in the hash table is selected and tested. Each offset is
|
||
tested until a match is found, or until a value of zero is found. This indicates that there is
|
||
no matching record in the data-base table. So the search fails. No error message is
|
||
produced, just no record is output.
|
||
|
||
As an example, consider again our mailtable:
|
||
|
||
Number Name Company Phone
|
||
|
||
1 Ronald McDonald McDonald’s (111) 222-3333
|
||
2 Chiquita Banana United Brands 1234
|
||
|
||
To prepare mailtable for a hash-table search, use the command:
|
||
index -mh mailtable Name
|
||
|
||
This hashes the contents of the Name column, and writes the results into file mailtable.h:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 118 / Buchseite 108 ====
|
||
108 Fast-Access Methods
|
||
|
||
For example The 104 in the fourth row of the hash table mailtable.h is the byte offset of the
|
||
first record in the data base mailtable table. The value ‘4’ (for fourth row) is the result of
|
||
adding the ASCII values of Ronald McDonald together and modulo with 5, the number of
|
||
rows in the hash table. The size of the hash table is two times the number of rows in the
|
||
table to be indexed, plus one. Having twice as many hash rows makes it likely that there
|
||
will be lots of zeros to stop the search for keys. If the hash table is twice as big as the
|
||
number of keys to hash, then only two probes are needed on average.
|
||
|
||
Thus, when the search command is searching a table via a hash-key index, it does the
|
||
following:
|
||
|
||
° Read the field on which the key has been built.
|
||
° Sum the key’s ASCII values.
|
||
|
||
° Modulo the sum by the number keys in the hash table (that is, the number of rows in
|
||
the data table, times two, plus one. This yields the number of the row to read in the
|
||
hash table.
|
||
|
||
° Read the appropriate row in the hash table to find the offset of the row in the data
|
||
table that we want.
|
||
|
||
° Use that offset to read the row out of the data table.
|
||
|
||
Hash is usually the fastest method. But it is best for a static file that you are not updating
|
||
and do not need to keep sorted.
|
||
|
||
Inverted or Indexed Sequential
|
||
|
||
The inverted method projects the key columns and the offset of each row and sorts on the
|
||
key columns to create a secondary index file. Then the search command can use a binary
|
||
search on the key columns to find the right offset into the data-base table.
|
||
|
||
Consider once again our mailtable:
|
||
|
||
Number Name Company
|
||
|
||
1 Ronald McDonald McDonald’s (111) 222-3333
|
||
2 Chiquita Banana United Brands 1234
|
||
|
||
To prepare an inverted index for on its column Name, type:
|
||
index -mi mailtable Name
|
||
This yields table mailtable.i, which appears as follows:
|
||
|
||
Offset Name
|
||
|
||
156 Chiquita Banana
|
||
104 Ronald McDonald
|
||
|
||
Note that the Name column has been projected and sorted and that the offset column
|
||
contains the corresponding offset in the main table.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 119 / Buchseite 109 ====
|
||
Fast-Access Methods 109
|
||
|
||
Partial Inital Match
|
||
|
||
The -x option specifies that partial initial match is to be used. This means you can use only
|
||
the first few letters of a key, and a match will be made on all those records whose key is
|
||
matched up to that point. When you type:
|
||
|
||
search -mi -x mailtable Name
|
||
|
||
search prints the head line and dash line, then wait for you type the key for which to
|
||
search. If you type:
|
||
|
||
Ron
|
||
then search prints:
|
||
1 Ronald McDonald McDonald’s (111) 222-3333
|
||
As you can see, Ron matched the first few characters in “Ronald McDonald”.
|
||
|
||
This method of searching helps save you unnecessary keystrokes; but on large tables it will
|
||
retrieve more rows than you really want.
|
||
|
||
B-tree
|
||
|
||
B-tree subroutines are now a standard on computer systems, for those who want to return
|
||
to software prisons; but of course the easiest to use and most general tree routines are to be
|
||
found, as usual, in the power of COHERENT itself. What is the hierarchical directory
|
||
structure but a collection of shell level programs to manipulate a tree? You can use the
|
||
directory structure itself to implement the first few levels of (tree structured) indices.
|
||
|
||
For example. in a company data base, you can have a directory for each city; within each
|
||
city directory, a directory for each department; within each department directory, a file for
|
||
each employee, each such file having header records and one employee record. Then, to
|
||
retrieve all the New York sales employees whose names begin with J, one could say:
|
||
|
||
union nyork/sales/J*
|
||
and, to retrieve all sales employees:
|
||
union */sales/*
|
||
|
||
COHERENT itself has many programs to manipulate trees. So there was no point in
|
||
duplicating the power of COHERENT.
|
||
|
||
The tree method is occasionally appropriate, but usually the most expensive in space
|
||
requirements. Its advantages are in rapid updates, deletes, and inserts of new records in
|
||
very large data bases. If you have a very large data base that requires lots of updates, it's
|
||
really quite fast to build the first few levels of indexing into the COHERENT directory
|
||
structure, but it does involve extra file system overhead.
|
||
|
||
Analysis
|
||
|
||
It takes analysis and testing to determine which is the best method for a given situation.
|
||
Each method has its advantages and disadvantages. Theory only takes one so far. You can
|
||
time the different methods on your computer to determine the fastest.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 120 / Buchseite 110 ====
|
||
110 Fast-Access Methods
|
||
|
||
To determine the best method to use in a situation, you must both analyze and test your
|
||
different options. The advantages and disadvantages of each method is discussed earlier.
|
||
You should also test any strategy you adopt. You might find that a simpler method is fast
|
||
enough, or the overhead of a fast method outweighs the benefits of speed.
|
||
|
||
Management
|
||
|
||
Fast-access methods need to be managed. If the files are being updated, they may have to
|
||
be reindexed. Reindexing takes time. You may want to schedule it when users are not
|
||
accessing the data and perhaps when the computer is not being used much. A nightly
|
||
reindexing may be appropriate.
|
||
|
||
The COHERENT command at lets you schedule big jobs like this, at say 3 A.M.. when the
|
||
system is more likely to be quiet. When you choose an access method, you must plan for
|
||
any management that is needed. This can also be accomplished by writing a command into
|
||
the system file /etc/crontab.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 121 / Buchseite 111 ====
|
||
Section 11:
|
||
Miscellaneous Commands
|
||
|
||
/rdb has more than 100 programs to help you develop software applications. Here is a brief
|
||
discussion of some of them, grouped together by subject.
|
||
|
||
Record Locking: One at a Time
|
||
|
||
When your application requires that several people update the same file at the same time.
|
||
you must lock records. When one user gets a record to change, it is important that no
|
||
other user pull out the same record and edit it also. If you allow this, the second record
|
||
written back will clobber the first record, thus destroying the results of the first user's
|
||
changes.
|
||
|
||
Many complain that the COHERENT system does not have a record-locking system. But it
|
||
is trivial to create record locking with COHERENT tools. /rdb provides lock and unlock
|
||
commands that you can use or modify for this purpose.
|
||
|
||
Finding What to Lock
|
||
To lock a record, /rdb must first find its location within the table where it “lives”.
|
||
|
||
To find the location of a record, use the seek command. It uses the fast-access method of
|
||
your choice to find the record and returns the starting and ending byte location, which can
|
||
be assigned to a shell variable.
|
||
|
||
For example, consider the command:
|
||
LOCATION=‘echo 5 | seek -mb -o tmp inventory Item’
|
||
A lot is going on here so let's take it step by step.
|
||
|
||
The echo command sent the number ‘5’ to the seek command. seek looks for an Item
|
||
numbered 5 in the inventory file using the binary fast access method (-mb), and writes the
|
||
record into the tmp file (-o tmp). seek sends a string of four numbers to standard out
|
||
which is assigned to the shell variable LOCATION. Echoing LOCATION gives us a resulting
|
||
of the form:
|
||
|
||
207 24509
|
||
|
||
The four numbers are the offsets of the first byte and last byte of the record in the data file.
|
||
and of the first byte and last byte of the offset in the secondary index file. (In this case it is
|
||
meaningless, because the binary method does not use a secondary file.)
|
||
|
||
lock and unlock
|
||
|
||
Now that we know where a record is, we can use the command lock to lock it while we work
|
||
with it, and the command unlock to unlock it once we're done with it.
|
||
|
||
The lock command writes the string from the LOCATION shell variable into a file in the
|
||
/tmp directory. It checks to see if that area of the file has been previously locked. The
|
||
unlock command removes the location line from the lock file.
|
||
|
||
111
|
||
|
||
==== PDF-Seite 122 / Buchseite 112 ====
|
||
112 Miscellaneous Commands
|
||
|
||
Blanking a Record
|
||
|
||
For added protection, or as an alternative, you can also blank out the record in the file. Use
|
||
seek to get the location, use blank to blank the record, and use replace to write the blank
|
||
record into the file,
|
||
|
||
For example, the following command blanks out line 5 in table inventory:
|
||
|
||
LOCATION=‘echo 5 | seek -mb -o tmp inventory Item’
|
||
blank < tmp | replace -mb inventory $LOCATION
|
||
|
||
When we look at inventory, it now appears as follows:
|
||
Item Amount Cost Value Description
|
||
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
|
||
3 5 80 400 clamps
|
||
|
||
4 23 19 437 plates
|
||
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
Line 5 has been replaced by a row of blanks. Since the data are no longer there, no other
|
||
user can grab them for manipulation. Users must be instructed. however, that a blank row
|
||
means that the record has been locked. If they retrieve a blank record, they must not
|
||
replace it with anything.
|
||
|
||
Dates: Conversion and Arithmetic
|
||
|
||
One of the basic tasks a data-base system must perform is manipulating dates. Each date
|
||
must be translated into a standard format, and users must be given a way to perform
|
||
arithmetic on dates. /rdb includes several programs help you handle dates.
|
||
|
||
Julian and Gregorian
|
||
|
||
Gregorian is the kind of dates we are all familiar with: January 1, 1989, 1/1/89, 890101,
|
||
and so on. Unfortunately, there are two problems with this kind of date: Gregorian dates
|
||
can not be added or subtracted, and they have several different formats. Fortunately, there
|
||
is another form of date, called Julian, that solves these problems. A Julian date is a
|
||
number of days since January 1, 4713 B.C., the date that marked the beginning of the
|
||
Julian calendar. Because a Julian date is an integer. you can add days to and subtract
|
||
days from a Julian date and get the correct new date.
|
||
|
||
/rdb has two commands that are used for this purpose. julian converts a date from the
|
||
standard Gregorian to Julian. It converts a whole column of dates so that they can be
|
||
operated upon. After the Julian dates have been manipulated, the column can be converted
|
||
back to Gregorian dates with the gregorian command.
|
||
|
||
For example, suppose you are planning a project. and have written a schedule into table
|
||
project, which appears as follows:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 123 / Buchseite 113 ====
|
||
Miscellaneous Commands 113
|
||
|
||
Date Description
|
||
890601 Start project
|
||
890701 Project crises
|
||
890801 Abandon project
|
||
890901 Coverup blame
|
||
891001 Write off losses
|
||
|
||
Now you find that you need to put off the start date of the project by 45 days. To update
|
||
your table to reflect this change, do the following:
|
||
|
||
° First, use the command julian to convert the Date column to Julian dates:
|
||
julian Date < project > tmp
|
||
The output has been written into table tmp, which appears as follows:
|
||
Date Description
|
||
|
||
1752623 Start project
|
||
1752653 Project crises
|
||
1752684 Abandon project
|
||
1752715 Coverup blame
|
||
1752745 Write off losses
|
||
|
||
Those huge numbers under Date are Julian days.
|
||
° We can now add 45 days to the column with the compute command:
|
||
compute ‘Date += 45’ < tmp > tmpl
|
||
The result is written into table tmp1, which appears as follows:
|
||
|
||
Date Description
|
||
|
||
1752668 Start project
|
||
1752698 Project crises
|
||
1752729 Abandon project
|
||
1752760 Coverup blame
|
||
1752790 Write off losses
|
||
|
||
Note that all of the Julian dates are 45 days later.
|
||
° Now we can convert back to Gregorian:
|
||
gregorian Date < tmpl > project
|
||
|
||
The result is written back into our original table, project, which now appears as
|
||
follows:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 124 / Buchseite 114 ====
|
||
114 Miscellaneous Commands
|
||
|
||
Date Description
|
||
890716 Start project
|
||
890815 Project crises
|
||
890915 Abandon project
|
||
891016 Coverup blame
|
||
891115 Write off losses
|
||
|
||
This can also be done in one pipeline:
|
||
|
||
julian Date < project |
|
||
|
||
> compute ‘Date = Date + 45’ |
|
||
> gregorian Date > tmp
|
||
|
||
mv tmp project
|
||
|
||
Difference
|
||
You can also find the difference between two dates.
|
||
|
||
For example, a building contractor may have a table called house, which contains the start
|
||
dates and stop dates for each phase of building a home:
|
||
|
||
Start Stop Days Step
|
||
|
||
890101 890118 Lay concrete
|
||
890121 890212 Setup frame
|
||
890215 890302 Build walls
|
||
890305 890401 Install fixtures
|
||
890408 890425 Sell at a loss
|
||
|
||
To compute the number of days for each step. we can use the julian and gregorian
|
||
programs on the house table:
|
||
|
||
julian Start stop < house |
|
||
compute ‘Days = Stop - Start’ |
|
||
gregorian Start Stop > tmp
|
||
|
||
mv tmp house
|
||
|
||
house now appears as follows:
|
||
|
||
Start Stop Days Step
|
||
|
||
890101 890118 17 Lay concrete
|
||
890121 890212 22 Setup frame
|
||
890215 890302 15 Build walls
|
||
890305 890401 27 Install fixtures
|
||
890408 890425 17 Sell at a loss
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 125 / Buchseite 115 ====
|
||
Miscellaneous Commands 115
|
||
|
||
Formats
|
||
|
||
There are a number of different formats that people use to express dates. The julian and
|
||
gregorian programs also allow you to convert between three different formats.
|
||
|
||
Computer
|
||
Computer date format is YYMMDD. For example, January 31, 1989, translates to
|
||
"890131". This format is best because it can be sorted, and is the most compact.
|
||
You can also test to see if one date is greater than another. Most users can quickly
|
||
get used to it.
|
||
|
||
US In the United States, dates are written in the sequence MMDDYY. For example,
|
||
January 31, 1989 translates to “1/31/89”.
|
||
|
||
European
|
||
The Europeans use the sequence DDMMYY. For example, January 31, 1989,
|
||
translates to 31/01/89.
|
||
|
||
Conversions
|
||
|
||
The /rdb commands julian and gregorian let you convert dates from one format to another.
|
||
Simply specify the current format to the julian command and another format that you want
|
||
to the gregorian command, and the format will change. The default format is computer
|
||
format.
|
||
|
||
For example, let's change the computer format in the project table to US format:
|
||
julian Date < project | gregorian -u Date
|
||
|
||
project now appears as follows:
|
||
|
||
Date Description
|
||
6/01/89 Start project
|
||
7/01/89 Project crises
|
||
8/01/89 Abandon project
|
||
9/01/89 Coverup blame
|
||
10/01/89 Write off losses
|
||
|
||
You can see one of the problems of the standard date is that it is eight characters. Since
|
||
the tabs are also eight characters, the next column has to move over. You can use the
|
||
justify command to pretty things up:
|
||
|
||
julian Date < project | gregorian -u Date | justify Date
|
||
project now appears as follows:
|
||
|
||
Date Description
|
||
6/01/89 Start project
|
||
7/01/89 Project Crises
|
||
8/01/89 Abandon project
|
||
9/01/89 Coverup blame
|
||
|
||
10/01/89 Write off losses
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 126 / Buchseite 116 ====
|
||
116 Miscellaneous Commands
|
||
|
||
Set-Theory Commands
|
||
|
||
In addition to the basic relational commands, there are several that come from relational set
|
||
theory.
|
||
|
||
Concatenating Tables
|
||
|
||
The union command appends one table to another, making a larger table consisting of all of
|
||
the rows of each.
|
||
|
||
For example, consider a set of accounting tables. The first table is called journalcash:
|
||
|
||
Date Account Debit Credit Description
|
||
|
||
891222 101 25000 cash from loan
|
||
|
||
891223 101 5000 cash payment
|
||
|
||
891224 101 15000 cash payment to CCPSC for parts
|
||
The second is called journalloan:
|
||
|
||
Date Account Debit Credit Description
|
||
|
||
891222 211.1 25000 loan number #378-14 Bank Amerigold
|
||
891223 211.2 5000 note payable to Zarkoff Equipment
|
||
And the third is called journaladjust:
|
||
|
||
Date Account Debit Credit Description
|
||
|
||
891224 130 30000 inventory - parts from CCPSsCc
|
||
|
||
Note that all three tables consist of the same set of columns.
|
||
|
||
Now, we use the union command to consolidate these subsidiary journals to create a
|
||
general journal:
|
||
|
||
union journalcash journalloan journaladjust > journal
|
||
|
||
Table journal appears as follows:
|
||
|
||
Date Account Debit Credit Description
|
||
|
||
891222 101 25000 cash from loan
|
||
|
||
891223 101 5000 cash payment
|
||
|
||
891224 101 15000 cash payment to CCPSC for parts
|
||
891222 211.1 25000 loan number #378-14 Bank Amerigold
|
||
891223 211.2 5000 note payable to Zarkoff Equipment
|
||
891224 130 30000 inventory - parts from CCPSC
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 127 / Buchseite 117 ====
|
||
Miscellaneous Commands 117
|
||
|
||
Subtract One Table From Another
|
||
|
||
The command difference lets us subtract one table from another to give the rows that are
|
||
in the first table but not in the second table.
|
||
|
||
For example, the following command finds the difference between two of the above-
|
||
described tables:
|
||
|
||
difference journal journalloan
|
||
|
||
This prints the following on the standard output:
|
||
|
||
Date Account Debit Credit Description
|
||
|
||
891222 101 25000 cash from loan
|
||
|
||
891223 101 5000 cash payment
|
||
|
||
891224 101 15000 cash payment to CCPSC for parts
|
||
891224 130 30000 inventory - parts from CCPSC
|
||
Intersect Between Tables
|
||
|
||
The command intersect lets us find the rows that are in both tables, the intersection of the
|
||
set.
|
||
|
||
For example, the following command finds the intersection between two of the above tables:
|
||
intersect journal journaladjust
|
||
|
||
It prints the following on the standard output:
|
||
|
||
Date Account Debit Credit Description
|
||
|
||
891224 130 30000 inventory - parts from CCPSC
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 128 / Buchseite 118 ====
|
||
118 Miscellaneous Commands
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 129 / Buchseite 119 ====
|
||
Section 12:
|
||
|
||
Combining /rdb with COHERENT
|
||
|
||
Much of your data-base work can be done with COHERENT commands. Many of the
|
||
traditional problems of data bases disappear when you have a COHERENT system. If you
|
||
have only one or a few users, problems like security, distributed data, concurrent access to
|
||
files, backup, checkpoint and recovery, validation, audit trails and logging, and others, are
|
||
minimized.
|
||
|
||
This chapter gives suggestions for combining /rdb with COHERENT tools to develop
|
||
solutions to these problems. This is not to say that there are no longer any problems.
|
||
There is still a role for programmers and system/analysts. But it is important for these
|
||
professional people, who got their experience on older systems, to re-think what they know
|
||
in light of the new tools and the new economics of our changing technology.
|
||
|
||
Multi-User Concurrent Access to Files
|
||
|
||
On small systems, you can assign each file to only one person. Then only one person need
|
||
access it at a time. Any number can append new records to a file at one time with the enter
|
||
command. Also, any number of users can read a table into their /rdb and COHERENT
|
||
commands, since reading does not change the table.
|
||
|
||
The only problem that arises is when two or more people must edit a table or list file at the
|
||
same time. Files can be locked in several ways. There is a lock and an unlock command
|
||
for this purpose. With the blank and replace commands, you can blank out a record while
|
||
you have it out for edit. The update commands does this.
|
||
|
||
Each user can move (mv) the file to a new name before editing it. Perhaps they might move
|
||
it into their own directories, make their changes and move it back. That way other users
|
||
will not find the file when they try to edit it. This is how the vilock command works.
|
||
Application programs can change the permission of a file so that it is read only to others on
|
||
the system, when our user is updating it.
|
||
|
||
There are also the lock and unlock commands, which are shell scripts to show how easy it
|
||
is to solve this problem with COHERENT tools.
|
||
|
||
Screen Form Entry
|
||
|
||
If you want to put forms on the terminal screen for the users to input data into, you can use
|
||
ve or the screen program. screen takes a form you create in a text editor, as with the
|
||
report command, and creates a shell script that will display the form. read the user's input
|
||
and output a table. Because it is a shell script, it can be edited to do a lot more including
|
||
validation, table lookup, and others. ve also takes a form, like the report command's form,
|
||
and creates a table.
|
||
|
||
119
|
||
|
||
==== PDF-Seite 130 / Buchseite 120 ====
|
||
120 /rdb and COHERENT
|
||
|
||
Security
|
||
|
||
You can handle security by physically protecting the computer and the terminal, by using
|
||
the COHERENT security permissions on files and directories, and by encrypting files. ve
|
||
contains special security features like unwriteable and invisible fields. There are read,
|
||
write, and execute permissions for the owner of the file. the group, and anyone on the
|
||
computer. See the COHERENT commands chmod and crypt.
|
||
|
||
Backup
|
||
|
||
You should backup the /rdb tables and list files just like regular COHERENT files. You can
|
||
simply copy a file or a whole directory to a backup media like magnetic tape, cassette tape,
|
||
or floppy disk, or transmit to another computer for backup. The COHERENT ustar and
|
||
cpio commands can be used for putting an entire directory structure into a single file.
|
||
|
||
Checkpoint and Recovery
|
||
|
||
You can always create a copy of a file that you are working on. /rdb commands do not alter
|
||
their input files. They simply create new files or pass their output (pipe) to another
|
||
program. In a crash, the original file is not harmed. Only the editors modify the existing
|
||
file and at least one. vi, has a crash recovery system.
|
||
|
||
Validation
|
||
|
||
ve provides programmable validity checks for data as it is entered. awk scripts and other
|
||
programs can be developed to check the validity of operator input. The vi editor has the
|
||
ability to assign to a single key a complex program. It can be used to validate each line
|
||
typed. The /rdb command validate is available to do any data validation from simple to
|
||
complex. See the sections on validation in the /rdb manual and the ve chapter.
|
||
|
||
Audit Trails and Logging
|
||
This is very easy because of the diff command.
|
||
At the end of each day's work the diff program can be run like this:
|
||
diff todaysfile yesterdaysfile > todayslog
|
||
|
||
The file todayslog will contain all lines that have changed since yesterday. Save it and you
|
||
have a log or audit trail. It can also be used for recovery to any date in the past.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 131 / Buchseite 121 ====
|
||
Section 13:
|
||
|
||
Other Data-Base Systems
|
||
|
||
Many data-base management systems are available. Each has its strengths and
|
||
weaknesses. However, they usually take a traditional approach. Such systems were
|
||
developed on operating systems that provide only a fraction of the services that COHERENT
|
||
provides. Therefore, the data-base developers had to write as much functionality into their
|
||
data-base packages as they could. When these data-base management systems are moved
|
||
to the COHERENT environment, they require that you leave COHERENT tools and all of
|
||
their power behind, and go into a software box where you are limited to the functions that
|
||
the data base developers have supplied.
|
||
|
||
There are many other data-base packages running on COHERENT systems, but they all
|
||
take this traditional big box approach. One usually finds that functions COHERENT tools
|
||
could provide are not available inside those data-base system boxes. There is usually no
|
||
good way to get the data out to COHERENT and back. It was the frustration of knowing
|
||
that we could do what we needed to do with COHERENT tools, but that our data was locked
|
||
up in the data base package, that originally prompted the development of /rdb.
|
||
|
||
With /rdb you always have access to the full power of the COHERENT system, because
|
||
/rdb commands are COHERENT commands that can be piped together with other
|
||
COHERENT commands. They extend the power of COHERENT tools rather than waste it.
|
||
/rdb works at the shell level and allows you to use all of the COHERENT utilities and
|
||
powers. With shell programming you can build applications easily with both COHERENT
|
||
and /rdb commands mixed and piped together.
|
||
|
||
With other data-base systems, you must learn a whole new language/syntax that is unique
|
||
to that data-base package. Learning /rdb is learning the COHERENT system, which is
|
||
useful in many applications. Or you can use the COHERENT knowledge you have already
|
||
acquired. In fact. it is an excellent way to learn COHERENT tools, just as many people
|
||
learned computers starting with a spreadsheet program.
|
||
|
||
Resource Use
|
||
|
||
When conventional data base systems duplicate COHERENT functions, programs become
|
||
huge. These programs take up tremendous amounts of computer memory and other
|
||
resources. Most data base packages will severely impact even large expensive computers
|
||
with only a few users. By doing things the COHERENT way, only the small programs that
|
||
are needed are brought in from the disk, putting only a light load on the system. This can
|
||
save hundreds of thousands of dollars in computer hardware, to say nothing of software.
|
||
|
||
C Programming Unnecessary
|
||
|
||
The COHERENT system has many programming languages, including the C language.
|
||
Although many programmers naturally think they must use such programs in their work, it
|
||
is usually unnecessary. Putting together COHERENT programs will usually accomplish
|
||
whatever is needed.
|
||
|
||
Although much can be done with the basic COHERENT system as delivered, some data-
|
||
base facilities and tools are missing or are hard to create. Therefore, a number of relational
|
||
data-base management systems have been developed for the COHERENT system.
|
||
|
||
121
|
||
|
||
==== PDF-Seite 132 / Buchseite 122 ====
|
||
122 Other Data-Base Systems
|
||
|
||
Unfortunately, most come from other operating systems and ignore the power of
|
||
COHERENT. On other operating systems, virtually nothing exists to help the developer and
|
||
user. Everything must be programmed from scratch. If the developer or the user is to have
|
||
a feature, it must be programmed into the data base program.
|
||
|
||
On COHERENT the reverse is true. Much of what you need is already available in the
|
||
COHERENT environment. The traditional data base management systems, when moved to
|
||
COHERENT, discourage the developer and user from getting access to these powerful and
|
||
familiar COHERENT tools. It is as if these systems create an unfamiliar box that you must
|
||
go into, leaving the power of COHERENT behind.
|
||
|
||
/rdb, however, was built for the COHERENT environment. It consists of over 100
|
||
COHERENT-like commands that fit together nicely with other COHERENT commands. It
|
||
has the tools that were found to be needed from real experience of developing software
|
||
applications. Using COHERENT shell programming, developers can quickly put together
|
||
applications from both COHERENT and /rdb commands. Users face a unified environment.
|
||
They may not know or care whether the commands they use come from the COHERENT
|
||
system or /rdb. This is the correct way to extend the COHERENT system: keeping the power
|
||
and genius of the COHERENT system and adding functions to it.
|
||
|
||
Speed
|
||
|
||
Most of the research on data bases and their problems assumes that you have huge files,
|
||
need to find a record (row) very quickly, and have many users. Not many years ago. few
|
||
could afford to have the power that a microcomputer offers today. Then computers cost
|
||
millions of dollars and had to be shared by many users. Only large volume applications
|
||
were cost effective enough to computerize, leading to a tremendous concern for speed and
|
||
size. Early eight-bit microcomputer systems reinforced this thinking. With weak
|
||
computers, small memories. and floppy disks, size and speed were still overriding issues.
|
||
|
||
Today, and more so in the future, we have powerful 16- and 32-bit microcomputers with
|
||
large memories and big disks, but so inexpensive that they are ubiquitous. Applications
|
||
will run faster and handle larger data bases. Now we want ease of use and powerful
|
||
systems. The bulk of data base applications are for relatively small data files of a few
|
||
hundred to several tens of thousands of records, with a small number of frequently asked
|
||
queries. If you think of something new to do that was not planned for in the development of
|
||
the application, you will usually find it very difficult or impossible to do. These traditional
|
||
data bases often require complicated setups. lots of training to use and are difficult to
|
||
modify. Worse still, they are huge programs that take up much of the memory and CPU
|
||
cycles of the computer. Only a few users can slow a big expensive computer down to an
|
||
unacceptable response. These traditional data base systems have features built into a large
|
||
program. The COHERENT system has lots of features, but they are in the hundreds of
|
||
programs stored on the hard disk. COHERENT only brings in the code it needs for a
|
||
particular function. The average COHERENT utility is about 40 kilobytes. Traditional data
|
||
base programs are often a quarter of a megabyte and larger.
|
||
|
||
/rdb takes a much different approach. It is much closer to the ideas of a text editor,
|
||
spreadsheet and, of course, the COHERENT system. It handles small data bases as well as
|
||
large. /rdb is aimed at ease of use and maximum power. Even so, it is usually very fast.
|
||
But when more speed is needed, /rdb also has not one but five fast-access methods to give
|
||
a variety of ways to access large files. /rdb is as fast or faster than most other data base
|
||
management system. Furthermore, even grep with its sequential search is not so bad.
|
||
grep is a COHERENT program which looks for a string pattern and prints out each line in
|
||
which it finds a match. Remember that there is computing overhead for the traditional fast
|
||
access methods. Binary searches require sorting, hash tables must be computed, B-trees
|
||
must split their pages when they fill, linked lists must maintain their pointers, and so on.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 133 / Buchseite 123 ====
|
||
Other Data-Base Systems 123
|
||
|
||
Size
|
||
|
||
As the size of our tables diminishes, so do the advantages of the fast access methods. bm,
|
||
an implementation of the Boyer-Moore linear search algorithm that is quite a bit faster than
|
||
grep but limited to fixed strings (not patterns), is distributed with /rdb. in the S$RDB/Llib
|
||
directory.
|
||
|
||
Many data-base comparisons put great emphasis on the size of the data base that can be
|
||
handled. This is really a problem for data-base systems that are one large program. /rdb,
|
||
however, is a group of small programs which can be piped together. Its only limits are those
|
||
of your hardware and COHERENT itself.
|
||
|
||
A table can be as big as the available free space on your disk, or as big a file as your
|
||
COHERENT system can handle. Use the COHERENT commands df to see how much space
|
||
is left on the disk, and use the COHERENT command du to see how much disk space a
|
||
given directory uses. For details, see these commands’ entries in the Lexicon.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 134 / Buchseite 124 ====
|
||
124 Other Data-Base Systems
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 135 / Buchseite 125 ====
|
||
Section 14:
|
||
|
||
Can You Say that in English?
|
||
|
||
If you are not a mathematician, you may find the literature on relational data bases to be
|
||
incomprehensible. One problem is the terms used in the literature. Different terms are
|
||
used by the mathematicians, computer people, and other humans.
|
||
|
||
We try to use human terms throughout the /rdb documentation. We lapse into computer
|
||
terms either by mistake, or when we think we are talking to programmers and analysts
|
||
about the more technical details. We ignore the mathematicians, since they seem to ignore
|
||
us. But we love them. Without them we would not have relational theory. Here is a table
|
||
that will help each group translate terms used by another group:
|
||
|
||
Humans Hackers Mathematicians
|
||
table....
|
||
|
||
number of columns.
|
||
number of rows
|
||
list of tables..
|
||
user's tables.
|
||
|
||
one concept per table.
|
||
get rows
|
||
get column
|
||
combine tables
|
||
new command...
|
||
|
||
Data-Base Models
|
||
|
||
A data-base model is a way of structuring and thinking about data. We use the relational
|
||
model, but there are several others. There are three major types of data base models that
|
||
have been implemented in several commercially successful data base management systems:
|
||
relational, network, and hierarchical. In addition there are at least four more important
|
||
models discussed in the literature, but for which few implementations exist as yet: entity-
|
||
relationship, binary, semantic network. and infological [Tsichritzis. 1982]. We will probably
|
||
see more of them in the future.
|
||
|
||
The major difference between these models is their structure. As you read through these
|
||
descriptions, you will probably have a sense of deja vu. Each is quite similar to the other
|
||
with some differences. Remember that information in each model can be converted or
|
||
transformed into the other models.
|
||
|
||
125
|
||
|
||
==== PDF-Seite 136 / Buchseite 126 ====
|
||
126 Say It in English
|
||
|
||
Hierarchical
|
||
|
||
The hierarchical data base has a tree structure. (In computer science, trees have their roots
|
||
at the top and grow their branches and leaves downward.)
|
||
|
||
This type of data base was popularized by IBM. Their IMS data-base management system
|
||
has been widely used in the past. When the users build a data base, this structure must be
|
||
imposed upon their data. Some searches are speeded up (such as from classes to grades).
|
||
Others become difficult or impossible. e.g., What grades did an instructor give? The
|
||
emphasis is on speedy responses from older, slower, and usually heavily burdened
|
||
computers. The speed is achieved by anticipating standard searches and optimizing them.
|
||
But ad hoc queries (ones you just think up as you are working) are not only slow, but are
|
||
often difficult, even impossible, to do.
|
||
|
||
Network
|
||
|
||
The network type of data base has a two-level structure. Both Total and Image/Query are
|
||
examples of this approach. This model comes from a CODASYL committee standard. This
|
||
system is a little easier to build and use than hierarchical, but still requires that the user
|
||
know the structure and navigate through the links. It is difficult, if not impossible to get
|
||
from one detail file to another.
|
||
|
||
Relational
|
||
|
||
Relational data bases have what are called a flat file structure. All files are at the same
|
||
level. With such a structure and a set of commands like project, select, and join, one can
|
||
get all of the information out of the data base that has been put into it.
|
||
|
||
E. F, Codd of the IBM San Jose Research Laboratory proposed this relational model in the
|
||
early 1970s [Codd 1970]. Since then, the relational approach has captured the attention
|
||
and approval of most of the academic, and now business, researchers in the field. IBM is
|
||
converting to relational with its new System R data base management system. It uses SQL
|
||
for a user interface. Almost all of the data-base systems that have been built for
|
||
COHERENT are relational.
|
||
|
||
A relational data base management system is considered by most researchers in the field as
|
||
the best for several reasons. Relational data bases have a solid mathematical base in
|
||
relational set theory, relational algebra and relational calculus. There are theorems in this
|
||
relational mathematics that prove that any data put into a relational data base can be
|
||
extracted. The mathematical base also assures us that the manipulations we perform will
|
||
have correct results, just as arithmetic assures us that the mathematics functions we
|
||
perform on the computer have correct results.
|
||
|
||
The relational structure is the simplest. All information is kept in simple tables. The user
|
||
does not have to navigate through complex networks (network model) or tree structures
|
||
(hierarchical model). Relational theory has tables (relations) with rows (tuples) and columns
|
||
(attributes of domains), which anyone can understand.
|
||
|
||
It also has functions on tables: project (column), select (row). join (jointable), and so on.
|
||
These functions both input and output tables, just as the functions in algebra which we are
|
||
familiar with input and output numbers (scalars), lists of numbers (vectors), or arrays of
|
||
numbers (matrixes). These commands we've discussed earlier. They are the most
|
||
frequently used.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 137 / Buchseite 127 ====
|
||
Say It in English 127
|
||
|
||
There are also several commands from set theory that are not as often used but are
|
||
important for completeness. There has been a lot written on relational data base systems
|
||
and theory. See the Bibliography.
|
||
|
||
Entity-Relationship
|
||
|
||
The entity-relationship model was put forth by Chen [Chen 1976]. This model sees the
|
||
universe, or more practically the company or institution, as composed of entities and
|
||
relations between them. Things, people, departments, and so on, are entities. Entities have
|
||
relationships between them. A department is part of an enterprise. People work in
|
||
departments as staff members. Equipment is assigned to departments. Some people are
|
||
heads of departments. One can draw a diagram of these entities and relationships.
|
||
|
||
There is a one-to-many relationship. A department can have many staff people and many
|
||
pieces of equipment. But each employee and piece of equipment is assigned to only one
|
||
department. If the rules of the organization change, so will this graph.
|
||
|
||
This model has similarities to the three classic models. The relational model holds entities
|
||
in tables (also called relations). It provides the jointable command to combine tables on
|
||
keys in which. there is a relationship between the entites of one table and another. It can
|
||
also be seen as hierarchical and network because of the structures. This model trys to
|
||
capture the overall structure of the enterprise regardless of how it is implemented. It is the
|
||
big picture.
|
||
|
||
Binary
|
||
|
||
The binary model sees data as a graph in which each node is a simple column or field of
|
||
data and the arcs that join the nodes represent simple relationships between them. It is
|
||
based on graph theory. As we move to computer systems with powerful graphic screens,
|
||
this model might become more common.
|
||
|
||
Semantic Network
|
||
|
||
The semantic-network model comes from the field of artificial intelligence (Al). (See Quillian
|
||
[1968] and Sowa [1983]). Al is the part of computer science that trys to get computers to be
|
||
intelligent. Its subfields are games, expert systems, vision, robotics, natural-language
|
||
recognition, and others. Researchers came up with this model in trying to structure data
|
||
for these efforts, trying to understand the human associative memory. and trying to
|
||
understand natural language.
|
||
|
||
There are many variations of the semantic network model because many researchers have
|
||
written about different versions in the technical literature. In the broadest sense any graph
|
||
model is a semantic network model, including the entity-relationship and the binary model.
|
||
|
||
The new graphic terminals will make this graph model easier to display and input. Since all
|
||
information can be represented in this way, it will be a very powerful way to interact with
|
||
computers.
|
||
|
||
Infological
|
||
|
||
An infological model is the user's view of the application. There is a dream that some day a
|
||
user can simply communicate the structure of the application to the computer and the data
|
||
base system will be set up automatically — somewhere between a general data-base
|
||
management system and a specific application. Some elements exist today. The new
|
||
graphic terminal systems provide powerful tools to communicate with the user and give the
|
||
user the ability to specify needed applications pictorially. Work in this field will be fun and
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 138 / Buchseite 128 ====
|
||
128 Say It in English
|
||
|
||
productive for future users.
|
||
|
||
PROLOG: Programming in Logic
|
||
|
||
Finally, the PROLOG language adds logic programming on top of a data base model.
|
||
PROLOG is discussed more in the next chapter.
|
||
|
||
The Grand Unified Field Theory of Information
|
||
|
||
The Grand Unified Field Theory of Information is that all of the different structures of
|
||
information are simply transformations of each other. Natural language sentences and their
|
||
parses, predicate calculus, tables and relational algebra, graphs, and semantic networks are
|
||
simply different representations and transformations of information.
|
||
|
||
Each has its advantages and uses. People speak language and understand graphs.
|
||
Computers can parse language, store tables, and manipulate them through relational
|
||
algebra and predicate logic. Sentences can be converted to predicate calculus formulas and
|
||
solved by comparing with the table data base.
|
||
|
||
This offers enormous power and possibilities. In the years ahead the written literature of
|
||
many fields can be scanned by computer, parsed, and inserted into tables. Then written or
|
||
spoken queries can be parsed and converted into predicate calculus formulas which can be
|
||
evaluated against the relational table data base. The computer can then speak, write, or
|
||
draw a graph or a picture of the answer.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 139 / Buchseite 129 ====
|
||
Section 15:
|
||
|
||
PROLOG and Al
|
||
|
||
Artificial-intelligence programs, like most programs, rely heavly on data bases. /rdb has
|
||
several facilities to assist Al, and especially expert system programs.
|
||
|
||
PROLOG Language and Environment
|
||
|
||
PROLOG is a programming language that allows you to program in logic. It was developed
|
||
in Europe, and has been adopted as the language for the Japanese Fifth Generation
|
||
Computer project. It is used in artificial intelligence work. It provides a powerful new
|
||
method to make logical inferences from data bases. Instead of being able to find data only,
|
||
it can reason from that data to answer questions that are not in the data base, but are
|
||
logically derivable from the data. This is an enormous leap in getting the computer to be
|
||
smart.
|
||
|
||
PROLOG is an entire programming language and environment, mainly because it was
|
||
developed on non-UNIX operating systems where almost nothing was provided. But we are
|
||
only interested in the logical searching features which are its major contribution. The logic
|
||
programming of PROLOG would be best placed in a UNIX/COHERENT environment with its
|
||
many tools, rather than in the primitive PROLOG environment.
|
||
|
||
If you are interested in working with PROLOG, COHware volume 2 contains, among many
|
||
other items, the source code for a PROLOG interpreter.
|
||
|
||
Predicate Calculus
|
||
|
||
The branch of logic that PROLOG uses is predicate calculus. This is not the calculus you
|
||
learned in math classes, but refers to the manipulation of formulas, of which the calculus
|
||
you are familiar with is only one form.
|
||
|
||
Almost all sentences in a natural language can be converted into predicate calculus
|
||
statements and manipulated logically. The sentence: Bill loves Kathy is written: loves(Bill,
|
||
Kathy). This says that there is a relationship, love, and that the first argument, Bill, has
|
||
that relationship with the second argument, Kathy. This predicate calculus formula can
|
||
also be expressed as a table:
|
||
|
||
Subject Object
|
||
|
||
Facts
|
||
|
||
PROLOG stores facts in the predicate calculus notation. Since almost any sentence can be
|
||
expressed, almost any information can be stored in the data base.
|
||
|
||
129
|
||
|
||
==== PDF-Seite 140 / Buchseite 130 ====
|
||
130 PROLOG and Al
|
||
|
||
PROLOG Means
|
||
female(michele).. .-michele is a female
|
||
female(jane).
|
||
|
||
male(john)...
|
||
|
||
male(shawn)... shawn is a male
|
||
|
||
..Shawn is a parent of jane
|
||
michele is a parent of jane
|
||
|
||
parent(shawn, jane).
|
||
parent(michele, jane)..
|
||
|
||
These facts are entered into PROLOG by simply typing them in or having PROLOG get them
|
||
from a file with the PROLOG consult command.
|
||
|
||
Questions
|
||
|
||
Once the above data are entered into the PROLOG data base, you can ask questions. The
|
||
following gives a sample PROLOG “question time” — the user's questions appear in Roman,
|
||
and PROLOG's replies in italics.
|
||
|
||
parent(shawn,jane)
|
||
yes
|
||
|
||
female(shawn)
|
||
|
||
no
|
||
mother(michele,jane)
|
||
no
|
||
|
||
The first query is found in the data base and yes is returned. The second and third queries
|
||
are not found in the data base, so no is returned. None of this is very exciting because any
|
||
data-base management system can do this. However, we humans know that the third
|
||
query is true because we know that if michele is the parent of jane and that michele is
|
||
female, then michele must be the mother of jane. But no data base can know this rule and
|
||
logically deduce this conclusion except PROLOG.
|
||
|
||
This great innovation of PROLOG comes when we add rules and logical inference to the data
|
||
base of facts. A rule is stated in this form:
|
||
|
||
mother(X,Y) :- parent(X,Y), female(X).
|
||
|
||
In English this rule says that the relationship mother exists between two entities X and Y if
|
||
(:-) X is the parent of Y and (,) X is a female. This rule is stored by PROLOG. Now we can
|
||
ask again:
|
||
|
||
mother(michele,jane)
|
||
yes
|
||
|
||
This time PROLOG gives the right answer. Not because it found the fact in the data base,
|
||
but because it inferred the fact from facts and rules in the data base. PROLOG failed to find
|
||
the fact in the data base, so it searched its list of rules for one that started with mother. It
|
||
then assigned michele to X and jane to Y. It went to the facts after the if (:-) symbol.
|
||
PROLOG first looked for the fact parent(michele,jane). It found that successfully, so it then
|
||
searched for the fact female(michele). This was also successful, so it responded with yes.
|
||
|
||
With a simple mechanism. we now have the ability to logically infer facts from other facts
|
||
and rules!
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 141 / Buchseite 131 ====
|
||
PROLOG and Al 131
|
||
|
||
/rdb Interface to PROLOG
|
||
|
||
/rdb provides an interface to PROLOG with two commands: tabletofact and tabletorule.
|
||
These convert /rdb tables into the predicate calculus formulas that PROLOG needs to see.
|
||
Therefore, we can logically query our data base.
|
||
|
||
tabletofact
|
||
|
||
The tabletofact command converts a table to predicate calculus. First let's look at our /rdb
|
||
fact tables. First. table female:
|
||
|
||
michele
|
||
beth
|
||
sandy
|
||
jan
|
||
|
||
Table male:
|
||
Male
|
||
|
||
kirk
|
||
rod
|
||
shawn
|
||
durk
|
||
|
||
Table parent:
|
||
Parent Child
|
||
|
||
michele rod
|
||
|
||
kirk rod
|
||
|
||
And finally, table isa:
|
||
Name Isa
|
||
|
||
rod human
|
||
|
||
human mammal
|
||
mammal animal
|
||
animal lifeform
|
||
|
||
Now let's convert them all to PROLOG fact format.
|
||
tabletofact female male parent isa > fact
|
||
|
||
File fact appears as follows:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 142 / Buchseite 132 ====
|
||
132 PROLOG and Al
|
||
|
||
female(michele).
|
||
female(beth).
|
||
female(sandy).
|
||
female(jan).
|
||
male(kirk).
|
||
male(rod).
|
||
male(shawn).
|
||
male(durk).
|
||
|
||
parent (michele, rod).
|
||
parent (kirk,rod).
|
||
isa(rod,human).
|
||
isa(human,mammal).
|
||
isa(mammal,animal).
|
||
isa(animal,lifeform).
|
||
|
||
tabletorule
|
||
|
||
Rules can also be stored in /rdb tables and converted to PROLOG format with the
|
||
tabletorule command. For example, consider table ruletable, as follows:
|
||
|
||
True If
|
||
|
||
mother (X,Y) female(X) , parent(X,Y)
|
||
father (X,Y) male(X) , parent(X,Y)
|
||
son(X,Y) male(X) , parent(Y,X)
|
||
isa(X,Y) isa(X,Z) , isa(Z,Y)
|
||
|
||
The command
|
||
|
||
tabletorule ruletable > rule
|
||
|
||
writes the following into file rule:
|
||
|
||
mother(X,Y) :- female(X) , parent(X,Y).
|
||
father(X,Y) :- male(X) , parent(X,Y).
|
||
son(X,Y) :- male(X) , parent(Y,X).
|
||
isa(X,Y) :- isa(X,Z) , isa(Z,Y).
|
||
|
||
Then you can consult these files within PROLOG with the consult command.
|
||
|
||
Now you are ready to ask questions. With this data base you can now ask questions about
|
||
motherhood and fatherhood, and questions like is rod a lifeform?
|
||
|
||
Problems of PROLOG
|
||
|
||
Richard Forsyth [Forsyth 1984, page 16] lists many complaints about PROLOG. These
|
||
include the following:
|
||
|
||
“PROLOG provides a relational data base for free — a big bonus, but the trouble is that It
|
||
resides in main memory, and ts consequently very greedy on storage.”
|
||
|
||
He also quotes Feigenbaum and McCorduck [1983]: “The last thing a knowledge engineer
|
||
wants Is to abdicate control to an ‘automatic’ theorem-proving process that conducts massive
|
||
searches without step-by-step control exerted by knowledge in the knowledge base.”
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 143 / Buchseite 133 ====
|
||
PROLOG and Al 133
|
||
|
||
The reason for all of the problems in PROLOG is that it is a great idea and a programming
|
||
environment. On non-COHERENT systems, when you want to do something, you wind up
|
||
having to do everything else also. You have to write editors, floating-point handlers (some
|
||
PROLOGs don't), trace, input/output, and on, and on. In addition, both PROLOG and LISP
|
||
do everything in memory. This is fine for small prototype and demonstration programs in a
|
||
university Al research lab, but unworkable for large data bases.
|
||
|
||
The same is true for LISP. Peter Jackson [Jackson 1986] writes about a classic expert
|
||
system: “The difference between MYCIN's score and those of Stanford experts was not
|
||
significant, but its score Is as good as the experts and better than the non-expert physicians.
|
||
However, MYCIN is not currently used in wards for a number of reasons ... it is written in
|
||
INTERLISP, is slow and heavy on memory ..."”
|
||
|
||
This problem is not new to the computer world. It was solved decades ago in commercial
|
||
computing. There needs to be a shift from memory to secondary storage as AI moves from
|
||
the research labs to real users. See Expert Database Systems: Proceedings From the First
|
||
International Workshop [Kerschberg 1986].
|
||
|
||
We also need to shift from PROLOG and LISP to UNIX/COHERENT and a powerful data-
|
||
base management system like /rdb. As radical as this sounds, one of the leading expert
|
||
system companies converted its system from LISP to COHERENT and C. They got a fifty-
|
||
fold increase in speed! The other expert-system companies are in various stages of
|
||
converting to UNIX.
|
||
|
||
On UNIX/COHERENT, you can simply add a new capability to an excellent environment.
|
||
PROLOG's environment is quite primitive and its inference system narrow and limited. The
|
||
PROLOG rule inference and search mechanism should be added to COHERENT as simply
|
||
more programs. We expect to see all of the Al ideas added to COHERENT in the years
|
||
ahead. We should see different logics, that is, fuzzy logic, Bayesian logic, multi-valued logic
|
||
and certainty factors. We should also see many new search strategies. Heuristic searches
|
||
guided by data in the data base are needed. Then we will see many new expert systems
|
||
developed with these vastly enhanced tools.
|
||
|
||
By concentrating on only what is new, developers can do a much better job. They won't
|
||
have to waste most of their time reinventing environment wheels.
|
||
|
||
searchtree: Data-Base Tree Searching
|
||
|
||
Most AI programs search data bases that can be visualized as trees or networks. Speeding
|
||
those searches and controlling them is a very important area of research. Usually, these
|
||
trees are kept in memory and searched with pointers. This limits the size of the data base
|
||
that a LISP or PROLOG program can handle. It is not as fast as one might imagine.
|
||
Memory searches are fast, but the overhead of bringing the data in off the disk, and hogging
|
||
so much memory that programs must swap frequently, quickly wipes out any theoretical
|
||
speed advantage.
|
||
|
||
searchtree is a /rdb shell program that shows another way to search a tree. It can use the
|
||
fast access methods to do a breadth first search of any sized data table. It is a shell
|
||
program example which can be edited to handle many search situations. Heuristics can be
|
||
built into the code to speed, or otherwise improve, the performance of the search.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 144 / Buchseite 134 ====
|
||
134 PROLOG and Al
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 145 / Buchseite 135 ====
|
||
Section 16:
|
||
|
||
/rdb and C
|
||
|
||
You can call COHERENT and the /rdb data-base commands from C programs. This
|
||
chapter gives you several example programs starting from the most simple to the most
|
||
complex.
|
||
|
||
Don’t Do It
|
||
|
||
Before we start, it is strongly recommended that you think twice before writing C or other
|
||
language programs. The shell, COHERENT tools, and /rdb commands are so powerful. fast.
|
||
and easy to develop, you seldom need to bother with the old third-generation programming
|
||
languages. If you think of writing a program in C by habit, try to break the habit. Always
|
||
try to do things in the COHERENT shell and /rdb first. Only resort to C when there is a
|
||
compelling reason. as opposed to a compulsion. We consider resorting to C as a failure of
|
||
imagination, or lack of knowledge or insight. in most cases. If you think you need a C
|
||
program, you may really need to know more shell programming tricks. Think of your
|
||
problems as a more general problem, and check to see if there is a COHERENT or /rdb
|
||
program that will do the job.
|
||
|
||
Speed is the most common excuse for descending to C coding. Remember that computers
|
||
are getting faster and cheaper. The RAM disk can greatly speed up COHERENT programs.
|
||
Also. try using the shell to implement a prototype. You can see if it is too slow before
|
||
coding. Often our intuitions are wrong in these matters. Also, the users might change their
|
||
minds and decide on a different way to approach the problem. Your prototype will then
|
||
have saved you a lot of unnecessary C coding.
|
||
|
||
If you do descend to C, try to write small programs that can be used in future shell
|
||
programming. Only write what you need. Read from the standard input and write to the
|
||
standard output. Make your programs table driven and use /rdb data-base table and list
|
||
formats so that the full power of COHERENT and the data base can manipulate the tables
|
||
that drive your programs.
|
||
|
||
system(): Tell Shell to Execute a Program
|
||
|
||
The easiest way for C programs to access both COHERENT and the /rdb data base is with
|
||
the COHERENT function system(). It only needs a character string, or pointer to a character
|
||
string that contains a shell command. system( will execute the command, just as though
|
||
you typed the command at the terminal or entered it into a shell program.
|
||
|
||
In the example below are three different ways of setting up the command string:
|
||
#define COMMAND “ls | we"
|
||
|
||
135
|
||
|
||
==== PDF-Seite 146 / Buchseite 136 ====
|
||
136 /rdb and C
|
||
|
||
main (argc, argv)
|
||
int argc;
|
||
char *argv [];
|
||
|
||
{
|
||
system ("echo hello word");
|
||
system (COMMAND) ;
|
||
system (argv [1]);
|
||
|
||
}
|
||
|
||
The first call to system( hard-codes the command in the code of the function call. The
|
||
second call uses a previously defined name COMMAND. Note the line
|
||
|
||
#define COMMAND
|
||
|
||
at the beginning of the code. Finally, the first argument on the command line is used as a
|
||
command string for system():
|
||
|
||
system (argv [1]);
|
||
This allows the user to type a command as the first argument and it will be executed.
|
||
|
||
The COHERENT command make is used to compile the program. It uses the Makefile,
|
||
whose contents are as follows:
|
||
|
||
system: system.o
|
||
cc system.o -o system
|
||
|
||
Thus, typing the command
|
||
make system
|
||
prints the following on the screen:
|
||
|
||
cc -O -c system.c
|
||
cc system.o -o system
|
||
|
||
This shows the steps COHERENT uses to compile and link your program. (For a full
|
||
description make, the programmer's best friend, see its tutorial in your COHERENT
|
||
manual.)
|
||
|
||
Now that the system program has been compiled, it can be run with a command as an
|
||
argument:
|
||
|
||
system date
|
||
This produces something like:
|
||
|
||
hello word
|
||
% 7 65
|
||
Thu Apr 3 02:10:04 PST 1986
|
||
|
||
Note that the first system call produced the hello world line. The second call executed the
|
||
defined command
|
||
|
||
ls | we
|
||
|
||
Note the output on the second line probably will differ on your system.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 147 / Buchseite 137 ====
|
||
lrdb and C 137
|
||
|
||
Finally, the date and time were displayed when the date argument to the system program
|
||
was executed by the call to system().
|
||
|
||
execl(): Execute a Call
|
||
|
||
The next step from simple to complex is the execl() function. This function will replace the
|
||
current process with another program. It is usually called chaining. Once called, the calling
|
||
process dies and is never reentered. The executed program takes over the process table
|
||
entry of the calling program and all of the open input and output files. Here is an example.
|
||
|
||
#include <stdio.h>
|
||
#define FIRST"First"
|
||
|
||
char *pl = "argument";
|
||
char *p2;
|
||
|
||
main (argc, argv)
|
||
|
||
int argc;
|
||
char *argv [];
|
||
{
|
||
p2 = “is:";
|
||
|
||
fflush (stdout);
|
||
execl ("/bin/echo", “echo", FIRST, pl, p2, argv[1], NULL);
|
||
¥
|
||
|
||
When we run the command
|
||
execl ARG1 ARG2
|
||
we see:
|
||
First argument is: ARG]
|
||
|
||
All of the arguments to execl( are pointers to strings; you can have as many as you want.
|
||
The last one must be NULL, as a sentinel or end marker.
|
||
|
||
In the first argument, the full path to the program to be executed must be given because
|
||
execl() does not search the PATH environmental variable. It is not good to hard code paths.
|
||
|
||
The second argument is the zero’th argument. which is the name of the called program.
|
||
The rest of the arguments are the normal arguments as you would type on the command
|
||
line at the shell level. Several possible ways of setting up the arguments are shown. The
|
||
first regular argument is a defined constant. p1 and p2 are each pointers to strings. The
|
||
first is initialized to a string when it is declared and the second is assigned later in the code.
|
||
Finally, the first argument passed to the calling program is passed on through the second
|
||
pointer in the argv array of pointers.
|
||
|
||
execi() Shell Programs
|
||
|
||
If you try to use execl() to execute a shell script file. it will fail. You have to execute a sh
|
||
shell program to read the text of the shell file. Here a shell file called istargs is executed. It
|
||
simply echoes out its arguments separated by newlines:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 148 / Buchseite 138 ====
|
||
138 /rdb and C
|
||
|
||
fork():
|
||
|
||
for I in $*
|
||
do
|
||
|
||
echo $I
|
||
done
|
||
|
||
Now, the program execl.sh.c, which executes listargs via execl():
|
||
|
||
#include <stdio.h>
|
||
#define FIRST "First"
|
||
|
||
char *pl = “argument";
|
||
char *p2;
|
||
|
||
main (argc, argv)
|
||
|
||
int argc;
|
||
char *argv [];
|
||
{
|
||
|
||
p2 = “is:";
|
||
|
||
fflush (stdout);
|
||
execl ("/bin/sh", "sh", “listargs", FIRST, pl, p2, argv[{1], NULL);
|
||
|
||
}
|
||
|
||
When executed with the command
|
||
execl.sh argl
|
||
|
||
you see:
|
||
|
||
First
|
||
argument
|
||
is:
|
||
|
||
argl
|
||
|
||
Note that sh is the program executed, and that its first argument is listargs. This is like
|
||
typing:
|
||
sh listargs
|
||
|
||
Create a Child Process
|
||
|
||
Sometimes we want to run another program without killing ourselves. The system call
|
||
fork( creates a child process that is identical to the calling program. The return value of
|
||
the fork() command can be tested to see which process the code is in, parent or child.
|
||
Therefore, the same program, with the same code, can branch to different statements,
|
||
depending upon whether it is the parent or child process. The child code can do its thing,
|
||
including executing another program. The parent process can wait for the child to finish
|
||
before going on. But it does not have to, because the COHERENT system is a multi-
|
||
processing environment.
|
||
|
||
The following program, fork.c, gives an example of using fork( in a C program:
|
||
|
||
#include <stdio.h>
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 149 / Buchseite 139 ====
|
||
rdb and C 139
|
||
|
||
#define FAIL -1
|
||
#define CHILD 0
|
||
#define PARENT 1
|
||
|
||
main (argc, argv)
|
||
|
||
int argc;
|
||
char *argv [];
|
||
{
|
||
|
||
switch (fork()) {
|
||
|
||
case -1: /* error */
|
||
fprintf (stderr, “fork system call failed.\n");
|
||
exit (FAIL);
|
||
|
||
case 0: /* child process */
|
||
execl ("/bin/echo", "echo", "I am the child.", NULL);
|
||
exit (CHILD);
|
||
|
||
default: /* parent process */
|
||
if (wait(NULL) != -1) {
|
||
fflush (stdout);
|
||
printf ("I am the parent.\n");
|
||
} else {
|
||
fflush (stdout);
|
||
fprintf (stderr, “wait system call failed.\n");
|
||
|
||
}
|
||
|
||
exit (PARENT);
|
||
}
|
||
|
||
When this program is compiled and invoked, you see the following on the standard output:
|
||
|
||
I am the child.
|
||
I am the parent.
|
||
|
||
This example uses the C switch() keyword execute fork(), because it has three different
|
||
return values. A -1 return indicates a failure to fork a new process. Perhaps the number of
|
||
processes has reached a limit. We want to handle this error condition.
|
||
|
||
A zero return means that the code is now in a child process, so the code should do the
|
||
child's thing. In this case, the child process executes an echo command with execl(). Thus.
|
||
it changes into another program.
|
||
|
||
Finally, the parent process gets the child's process ID number, which is some number
|
||
greater than zero. Here the parent waits for the child to die before printing its message. It
|
||
flushes the standard-out buffers before printing its own message.
|
||
|
||
You can see when we execute this program, both processes write to the standard output.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 150 / Buchseite 140 ====
|
||
140 /rdb and C
|
||
|
||
Pipes
|
||
|
||
A very important use of this mechanism is to use the pipe() system call to open a pipe
|
||
between the two processes so that they can exchange data. This can go either way. from
|
||
parent to child, or from child to parent.
|
||
|
||
One-Way Pipe
|
||
|
||
The first example here is of a one-way pipe. The next section will demonstrate a two-way
|
||
pipe.
|
||
|
||
#include <stdio.h>
|
||
|
||
#define FAIL -1
|
||
|
||
#define CHILD 0
|
||
|
||
#define PARENT 1
|
||
|
||
#define MESSAGE “Hi, kid"
|
||
|
||
main (argc, argv)
|
||
|
||
int
|
||
char
|
||
|
||
{
|
||
|
||
TUTORIAL
|
||
|
||
arge;
|
||
‘argv [1];
|
||
|
||
int pd [2];
|
||
char childbuf [BUFSIZ];
|
||
|
||
if (pipe(pd) == FAIL) {
|
||
fprintf (stderr, “pipe system call failed.\n");
|
||
exit (FAIL);
|
||
|
||
}
|
||
|
||
switch (fork()) {
|
||
|
||
case -1l: /* error */
|
||
fprintf (stderr, "fork system call failed.\n");
|
||
exit (FAIL);
|
||
|
||
case 0: /* child process */
|
||
if (close (pd [1]) == FAIL) {
|
||
fprintf (stderr, “close pipe failed.\n");
|
||
exit (FAIL);
|
||
}
|
||
|
||
read (pd [0], childbuf, BUFSIZ);
|
||
execl ("/bin/echo", “echo",
|
||
|
||
“child read:", childbuf, NULL);
|
||
exit (CHILD);
|
||
|
||
==== PDF-Seite 151 / Buchseite 141 ====
|
||
Itdb andC 141
|
||
|
||
default: /* parent process */
|
||
if (close (pd [0]) == FAIL) {
|
||
fprintf (stderr, “close pipe failed.\n");
|
||
exit (FAIL);
|
||
}
|
||
|
||
printf ("parent wrote: %s\n", MESSAGE, sizeof (MESSAGE) );
|
||
if (write (pd[1], MESSAGE, sizeof(MESSAGE)) == FAIL) {
|
||
fprintf (stderr, “pipe write filed\n");
|
||
exit (FAIL);
|
||
}
|
||
}
|
||
exit (PARENT);
|
||
}
|
||
|
||
When compiled and run, this program prints the following on the standard output:
|
||
|
||
parent wrote: Hi, kid
|
||
child read: Hi, kid
|
||
|
||
pd is the pipe-descriptor buffer, which holds two integers, one for each pipe direction. The
|
||
parent writes into pd[1] and the child reads from pd[0]. Each closes its other pipe with the
|
||
system call close(). fork() creates the child process. The parent process writes its message
|
||
to the pipe with the system call write(). It used the C sizeof operator to count the
|
||
characters of the MESSAGE. This allows us to edit the message and not have to look
|
||
through the code to find, count and change its size.
|
||
|
||
The child process reads the pipe with the system call read() and executes the echo
|
||
command to display the message it got from the parent process.
|
||
|
||
Of course this is not very useful, but it is simple enough to follow. It can be used in any
|
||
situation in which we want to crank up a background process and periodically send it data
|
||
to act upon. This mechanism is especially useful in COHERENT because there are so many
|
||
programs that are available to save us the effort of writing them.
|
||
|
||
Pipe to Standard Input
|
||
|
||
In the example above, write() was used to read the pipe and the message was passed on to
|
||
the executed echo program as an argument. But we also want to write to the standard
|
||
input of a COHERENT program. In the example below, the child executes a process that
|
||
reads from its standard input. The child connected the pipe to its standard input using the
|
||
system call dup():
|
||
|
||
#include <stdio.h>
|
||
|
||
#define FAIL -1
|
||
|
||
#define CHILD 0
|
||
|
||
#define PARENT 1
|
||
|
||
#define PM “Hi, kid"
|
||
#define cM “Hi, parent"
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 152 / Buchseite 142 ====
|
||
142 /rdb and C
|
||
|
||
main (argc, argv)
|
||
|
||
int argc;
|
||
char *argv []?
|
||
{
|
||
|
||
int pd [2];
|
||
char buffer [BUFSIZ];
|
||
|
||
if (pipe(pd) == FAIL) {
|
||
fprintf (stderr, "pipe system call failed.\n");
|
||
exit (FAIL);
|
||
|
||
}
|
||
|
||
switch (fork()) {
|
||
|
||
case -1: /* error */
|
||
fprintf (stderr, “fork system call failed.\n");
|
||
exit (FAIL);
|
||
|
||
case 0: /* child process */
|
||
if (close () == FAIL) {
|
||
fprintf (stderr, “close pipe failed.\n");
|
||
exit (FAIL);
|
||
}
|
||
|
||
if (dup (pd [0]) != 0) {
|
||
fprintf (stderr, “dup pipe failed.\n");
|
||
exit (FAIL);
|
||
|
||
}
|
||
|
||
if (close (pd [0]) == FAIL || close (pd [1]) == FAIL) {
|
||
fprintf (stderr, “dup pipe failed.\n");
|
||
exit (FAIL);
|
||
|
||
}
|
||
|
||
execl ("/bin/cat", “cat", NULL);
|
||
fprintf (stderr, “execl cat failed.\n");
|
||
exit (FAIL);
|
||
|
||
default: /* parent process */
|
||
if (close (pd [0]) == FAIL) {
|
||
fprintf (stderr, "close pipe failed.\n");
|
||
exit (FAIL);
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 153 / Buchseite 143 ====
|
||
/rdb andC 143
|
||
|
||
printf (“parent wrote: %s\n", PM, sizeof(PM));
|
||
|
||
if (write (pd[{1], PM, sizeof(PM)) == FAIL) {
|
||
fprintf (stderr, “pipe write filed\n");
|
||
exit (FAIL);
|
||
|
||
}
|
||
|
||
if (close (pd [1]) == FAIL) {
|
||
fprintf (stderr, “close pipe failed.\n");
|
||
|
||
exit (FAIL);
|
||
}
|
||
/*
|
||
read (pd [0], buffer, BUFSIZ);
|
||
printf ("parent read: %s\n", buffer);
|
||
*/
|
||
}
|
||
exit (PARENT);
|
||
}
|
||
|
||
When compiled and run, this program writes the following to the standard output:
|
||
|
||
parent wrote: Hi, kid
|
||
Hi, kid
|
||
|
||
This is similar to the example before, except that the cat command reads from its standard
|
||
input. The parent process then uses the system call close() to close the pipe after writing.
|
||
This sends an end-of-file character to the pipe and the standard input of the cat program,
|
||
so that the program will terminate.
|
||
|
||
Two-Way Pipe
|
||
In addition to sending data one way, we sometimes want to get replies. Two-way pipes
|
||
make possible co-routines that exchange data. The following gives an example of how to
|
||
implement a two-way pipe:
|
||
/*
|
||
pipe2 - sends first argument thru pipe to child program,
|
||
and reads the childs replay and sends it to standard-out.
|
||
*/
|
||
|
||
#include <stdio.h>
|
||
|
||
/* program return status */
|
||
|
||
#define OK 0
|
||
|
||
#define FAIL -1
|
||
|
||
/* fork return codes distinguished child from parent process */
|
||
|
||
#define CHILD 0
|
||
#define PARENT 1
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 154 / Buchseite 144 ====
|
||
144 /rdb and C
|
||
|
||
/* pipe descriptor array elements */
|
||
#define READ 0
|
||
#define WRITE 1
|
||
|
||
/* standard-io file descriptors */
|
||
#define STDINO
|
||
|
||
#define STDOUT 1
|
||
|
||
#define STDERR 2
|
||
|
||
/* program for child to execl */
|
||
|
||
#define PATH "“/usr/bin/bc"
|
||
|
||
#define PROGRAM "be"
|
||
|
||
/* standard-error handling macro */
|
||
|
||
#define error(message) {fprintf (stderr,"%s: %s\n", argv [0], message);\
|
||
exit (FAIL); }
|
||
|
||
char buffer [BUFSIZ]; /* buffer to read into */
|
||
|
||
main (argc, argv)
|
||
|
||
int argc;
|
||
char *argv [];
|
||
{
|
||
register char *p; /* pointer for scanning strings */
|
||
|
||
int pepipe [2]; /* pipe from parent to child */
|
||
int cppipe [2]; /* pipe from child to parent */
|
||
|
||
if (pipe (pcpipe) == FAIL || pipe (cppipe) == FAIL)
|
||
error("pipe system call failed.");
|
||
|
||
switch (fork()) {
|
||
case FAIL: /* error */
|
||
error("fork system call failed");
|
||
|
||
case CHILD: /* child process */
|
||
|
||
/* close stdin to free for pipe connection */
|
||
if (close (STDIN) == FAIL)
|
||
error("close stdin failed");
|
||
|
||
/* connect pipe to stdin of child */
|
||
if (dup (pepipe [READ]) != STDIN)
|
||
error("dup stdin pipe failed");
|
||
|
||
/* close stdout to free for pipe connection */
|
||
if (close (STDOUT) == FAIL)
|
||
error("close stdout failed");
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 155 / Buchseite 145 ====
|
||
Irdb andC 145
|
||
|
||
/* connect pipe to stdout of child */
|
||
if (dup (cppipe [WRITE]) != STDOUT)
|
||
error("dup stdout pipe failed");
|
||
|
||
/* close all pipes so child reads from stdin/out */
|
||
if (close (pcpipe [READ]) == FAIL ||
|
||
close (pcpipe [WRITE]) == FAIL | |
|
||
close (cppipe [READ]) == FAIL ||
|
||
close (cppipe [WRITE]) == FAIL )
|
||
error("close child pipes failed");
|
||
|
||
/* execute basic calculator */
|
||
exec] (PATH, PROGRAM, NULL);
|
||
|
||
/* if we get here, execl failed */
|
||
error("execl failed");
|
||
|
||
default: /* parent process */
|
||
|
||
/* close unused ends of the pipes */
|
||
|
||
if (close (pcpipe [READ]) == FAIL ||
|
||
close (cppipe [WRITE]) == FAIL )
|
||
error("parent close pipe failed");
|
||
|
||
/* write command line argument into pipe to child */
|
||
if (write (pcpipe [WRITE], argv [1], strlen(argv [1]))
|
||
== FAIL)
|
||
error("parent pipe write argv failed");
|
||
|
||
/* be needs a newline to execute a line */
|
||
if (write (pcpipe [WRITE],"\n", 1) == FAIL)
|
||
error("parent pipe write nl failed");
|
||
|
||
/* close pipe sends end-of-file to kill child */
|
||
if (close (pcpipe [WRITE]) == FAIL)
|
||
error("parent close pipe failed");
|
||
|
||
/* read childs reply */
|
||
|
||
if (read (cppipe [READ], buffer, sizeof (buffer) )
|
||
== FAIL)
|
||
error("parent pipe read failed");
|
||
|
||
/* be sure string is terminated by NULL */
|
||
|
||
for (p = buffer; *p != ‘\n'; ptt);
|
||
*p = NULL;
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 156 / Buchseite 146 ====
|
||
146 /rdb and C
|
||
/* output the answer */
|
||
puts (buffer);
|
||
exit (OK);
|
||
}
|
||
}
|
||
When this program is compiled and run with the command
|
||
pipe2 ‘2+2'
|
||
you'll see the following on the standard output:
|
||
4
|
||
Likewise, the command
|
||
pipe2 ‘'scale=2 ; (100/3) * 5°
|
||
prints:
|
||
166.65
|
||
The be command is the COHERENT calculator program. It reads equations from the
|
||
standard input and writes solutions to the standard output. Our Program reads an
|
||
equation from its first command-line argument, and writess it through one pipe to a child
|
||
process. The child process connects pipes to its standard input and standard output, then
|
||
executes be. be reads the equation and sends the answer to the parent through the second
|
||
pipe. The parent reads the second pipe and sends the solution to its standard output.
|
||
This program is not very useful, but is a template. You can use this mechanism to give
|
||
your C programs access to all of the COHERENT, /rdb, and other programs as if they were
|
||
subroutines. This will save you a lot of programming. If a program exists to do what you
|
||
want. use it.
|
||
Programming Style
|
||
|
||
The program above also introduces a more advanced programming style. Most magic
|
||
numbers have been defined to mnemonic constants to make the code easier to read and to
|
||
simplify changes. A zero appearing in the code usually means nothing to the reader, but a
|
||
name helps us understand what it is. In addition, if you have to change a magic number, it
|
||
is much easier to edit it once at the top of the code than to search through all of the code to
|
||
find it. It is especially difficult when the magic number is a common number like zero or
|
||
one. You can not globally change such numbers, because they are used in many different
|
||
ways. You must carefully search the code for the correct numbers to change.
|
||
|
||
Notice that the error condition is now handled by a simple macro called error(). It saves a
|
||
lot of typing. makes the code easier to read, and standardizes the way errors are handled
|
||
and reported.
|
||
|
||
Finally, every major section of code is commented. It takes a little more time, but saves a
|
||
lot of time when we are debugging, changing, and maintaining the program.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 157 / Buchseite 147 ====
|
||
/rdb andC 147
|
||
|
||
Fast Access
|
||
|
||
The final example shows a more practical program. This fastaccess program creates the
|
||
search program and sends it a key through the first pipe. This child process finds a row in
|
||
the inventory table and sends it back through the second pipe to the parent. In this
|
||
example, the parent merely writes the retrieved row to the standard output, but you can
|
||
modify the parent to do other things to the row.
|
||
|
||
/*
|
||
|
||
fastaccess - sends first argument thru pipe to child seek program,
|
||
and reads the childs offset replay, seeks the record,
|
||
reads it and sends the record to standard-out.
|
||
|
||
*/
|
||
|
||
#include <stdio.h>
|
||
|
||
/* program return status */
|
||
#define OK i)
|
||
#define FAIL -1
|
||
|
||
/* fork return codes distinguished child from parent process */
|
||
#define CHILD 0
|
||
#define PARENT 1
|
||
|
||
/* pipe descriptor array elements */
|
||
#define READ 0
|
||
#define WRITE 1
|
||
|
||
/* standard-io file descriptors */
|
||
#define STDINO
|
||
|
||
#define STDOUT 1
|
||
|
||
#define STDERR 2
|
||
|
||
/* program for child to execl */
|
||
|
||
#define PATH “/usr/rdb/bin/search"
|
||
#define PROGRAM "search"
|
||
#define METHOD “=mb"
|
||
|
||
#define TABLE “inventory”
|
||
|
||
#define KEY “Item"
|
||
|
||
/* standard-error handling macro */
|
||
#define error(message) {fprintf (stderr,"%s: %s\n", argv [0], message) ;\
|
||
exit (FAIL); }
|
||
|
||
char buffer [BUFSIZ]; /* buffer to read into */
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 158 / Buchseite 148 ====
|
||
148 /rdb and C
|
||
|
||
main (argc, argv)
|
||
|
||
int argc;
|
||
char *argv [];
|
||
|
||
{
|
||
|
||
register char *p; /* pointer for scanning strings */
|
||
pepipe [2]; /* pipe from parent to child */
|
||
eppipe [2]; /* pipe from child to parent */
|
||
|
||
file; /* file descriptor for table file */
|
||
from, to; /* offsets of record in table */
|
||
xfrom, xto; /* offsets in secondary index file */
|
||
|
||
int
|
||
int
|
||
int
|
||
int
|
||
int
|
||
|
||
if (pipe (pcpipe) == FAIL || pipe (cppipe) == FAIL)
|
||
error("pipe system call failed.");
|
||
|
||
switch (fork()) {
|
||
case FAIL: /* error */
|
||
error("fork system call failed");
|
||
|
||
case CHILD: /* child process */
|
||
|
||
TUTORIAL
|
||
|
||
/*
|
||
if
|
||
|
||
/*
|
||
if
|
||
|
||
/*
|
||
af
|
||
|
||
/*
|
||
if
|
||
|
||
/*
|
||
if
|
||
|
||
/*
|
||
|
||
close stdin to free for pipe connection */
|
||
(close (STDIN) == FAIL)
|
||
error("“close stdin failed");
|
||
|
||
connect pipe to stdin of child */
|
||
(dup (pcpipe [READ]) I= STDIN)
|
||
error("dup stdin pipe failed");
|
||
|
||
close stdout to free for pipe connection */
|
||
(close (STDOUT) == FAIL)
|
||
error("close stdout failed");
|
||
|
||
connect pipe to stdout of child */
|
||
(dup (cppipe [WRITE]) != STDOUT)
|
||
error("dup stdout pipe failed");
|
||
|
||
close all pipes so child reads from stdin/out */
|
||
(_ close (pepipe [READ]) == FAIL ||
|
||
close (pcpipe [WRITE]) == FAIL ||
|
||
close (cppipe [READ]) == FAIL | |
|
||
close (cppipe [WRITE]) == FAIL )
|
||
error("close child pipes failed");
|
||
|
||
execute program */
|
||
|
||
execl (PATH, PROGRAM, METHOD, TABLE, KEY, NULL);
|
||
|
||
/*
|
||
|
||
if we get here, execl failed */
|
||
|
||
error("execl failed");
|
||
|
||
==== PDF-Seite 159 / Buchseite 149 ====
|
||
lrdb and C 149
|
||
|
||
default: /* parent process */
|
||
/* close unused ends of the pipes */
|
||
if (close (pepipe [READ]) == FAIL ||
|
||
|
||
close (cppipe [WRITE]) == FAIL )
|
||
error("parent close pipe failed");
|
||
|
||
/* write command line argument into pipe to child */
|
||
if (write (pcpipe [WRITE], argv [1], strlen(argv [1]))
|
||
== FAIL)
|
||
error("parent pipe write argv failed");
|
||
|
||
/* needs a newline to execute a line */
|
||
if (write (pcpipe [WRITE],"\n", 1) == FAIL)
|
||
error("parent pipe write nl failed");
|
||
|
||
/* close pipe sends end-of-file to kill child */
|
||
if (close (pcpipe [WRITE]) == FAIL)
|
||
error("parent close pipe failed");
|
||
|
||
/* read childs reply */
|
||
if (read (cppipe [READ], buffer, sizeof(buffer) )
|
||
== FAIL)
|
||
error("parent pipe read failed");
|
||
|
||
/* output the answer */
|
||
puts (buffer);
|
||
|
||
exit (OK);
|
||
|
||
}
|
||
|
||
After you compile this program, the command
|
||
fastaccess 2
|
||
|
||
prints the following on the standard output:
|
||
|
||
Item Amount Cost Value Description
|
||
|
||
2 100 5 500 test tubes
|
||
|
||
This is similar to the last example. But here, several arguments are given to the search
|
||
program. These are defined with the #define preprocessor statements, but they could be
|
||
passed from the command line arguments of the parent program or created within the
|
||
program, or read from another file, a technique which is called table driven programming.
|
||
|
||
The best way to program is to write simple code that gets its parameters and data from
|
||
data-base tables. Then the programs can be easily modified by simply editing the driving
|
||
data tables, without having to reedit and recompile the source code. Users can modify these
|
||
programs without calling back the programmer.
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 160 / Buchseite 150 ====
|
||
150
|
||
|
||
/rdb and C
|
||
|
||
tabletostruct: Convert a Table to a C struct
|
||
|
||
A useful /rdb command is tabletostruct. It converts an /rdb table to a C-language struct
|
||
type and initializes it to the values in the table. You can compile this struct into your C
|
||
program and access any field. This makes possible table-driven code. You can use the data
|
||
base to enter and update your tables, and recompile the program when you wish. This is
|
||
the fastest access to tables, but requires compiling, and the inflexibility of not being able to
|
||
change the programs internally compiled tables while the program is running.
|
||
|
||
Here we start with a simple table, convert it to struct, make it a header file, and compile it
|
||
into a simple program that prints out each field.
|
||
|
||
To begin, we create a table called table, which appears as follows:
|
||
A B c
|
||
|
||
1 2 3
|
||
Now, we use tabletostruct to covert table to a struct:
|
||
tabletostruct Table table < table > table.h
|
||
The output is written into the header file table.h, which appears as follows:
|
||
|
||
struct Table
|
||
|
||
{
|
||
|
||
char *A;
|
||
|
||
char *B;
|
||
|
||
char *C;
|
||
|
||
} table [] =
|
||
{ "1","2","3" }
|
||
7
|
||
|
||
The following program displays the structed contents of table.h:
|
||
#include “table.h"
|
||
|
||
main ()
|
||
{
|
||
printf ("A=%s\n", table[0].A);
|
||
printf ("B=%s\n", table[0].B);
|
||
printf ("C=%s\n", table[0].c);
|
||
}
|
||
When compiled and run, the program prints the following onto the standard output:
|
||
|
||
A=1
|
||
B=2
|
||
Cc=3
|
||
|
||
Note that the struct is an array and that we have to give a subscript for each row we want.
|
||
We can also put the tabletostruct into the Makefile to further automate the re-compilation:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 161 / Buchseite 151 ====
|
||
/rdb and C 151
|
||
|
||
printtable: table.h printtable.o
|
||
cc -o printtable printtable.o
|
||
|
||
table.h: table
|
||
tabletostruct Table table < table > table.h
|
||
|
||
This says that the printable program depends upon table.h being up to date, and table.h
|
||
depends upon table being up to date. If you modify table since the last compile, make will
|
||
re-execute the tabletostruct command.
|
||
|
||
Our next example begins with a bigger table. called inventory. The command
|
||
tabletostruct Inventory inventory < inventory
|
||
writes the following to the standard output:
|
||
|
||
struct Inventory
|
||
|
||
{
|
||
|
||
char *Item;
|
||
|
||
char *Amount;
|
||
|
||
char *Cost;
|
||
|
||
char *Value;
|
||
|
||
char *Description;
|
||
|
||
} inventory [] =
|
||
|
||
{ . 4"," 50"," 150","“rubber gloves" }
|
||
|
||
ry | 100°," 5"," 500","“test tubes" }
|
||
|
||
rf 5"," 80"," 400","clamps" }
|
||
|
||
al 23"," 19"," 437","plates" }
|
||
|
||
Pi 99"," 24"," 2376","cleaning cloth" }
|
||
Pe g9"," 147","13083","bunsen burners" }
|
||
ef 5"," 175"," 875","scales" }
|
||
|
||
7
|
||
|
||
You can refer to the Description of the third item with this code:
|
||
printf ("Item Name = %s\n", inventory [2].Description) ;
|
||
|
||
Remember that tables in C start with element 0. You can convert the strings to integers
|
||
with the function atoi():
|
||
|
||
int item; /* current inventory item number */
|
||
int row; /* current row number starting from 0 */
|
||
|
||
item = atoi (inventory [row].Item);
|
||
|
||
Read Table into Memory: getfile() and fsize()
|
||
|
||
To get tables from the data base at run time, you can read the table into memory and set up
|
||
an array of pointers to reference any field by row and column number. Use the COHERENT
|
||
system calls open() and stat() to get the size of the table, and the function malloc() to get
|
||
that much memory. Then use read() to copy the whole table into memory and run throu
|
||
|
||
it with a loop that sets a two-dimentional array of pointers to point to every field in the
|
||
array. Then you can reach any field with:
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 162 / Buchseite 152 ====
|
||
152 /rdb and C
|
||
|
||
char *field, *p_table [][];
|
||
int row, column;
|
||
|
||
field = p_table [row][column];
|
||
|
||
To keep from having to hard code the size of your pointer table. first find out how many
|
||
columns and rows you have by running through the memory counting newline characters.
|
||
You might turn tabs and newlines into NULs while you go. Then malloc() enough memory
|
||
to hold this array of pointers and run through the memory again to set the pointer array to
|
||
pointing to fields.
|
||
|
||
Here are some routines that show examples of how to do this.
|
||
|
||
/*
|
||
|
||
Copyright (c) 1990, 1991 Schaffer and Wright
|
||
|
||
getfile - reads a file into memory and returns pointer and size
|
||
|
||
*/
|
||
|
||
#include “rdb.h"
|
||
#include <sys/types.h>
|
||
#include <sys/stat.h>
|
||
|
||
char *filebuffer, *malloc();
|
||
int file, open(), read();
|
||
long fsize ();
|
||
|
||
char *getfile (filename, p_size)
|
||
|
||
char *filename;
|
||
unsigned *p_size;
|
||
{
|
||
|
||
*p_size = 0;
|
||
|
||
/* open the file */
|
||
if ((file = open (filename, 0)) < 0) {
|
||
fprintf (stderr, “Can’t open file %s.\n", filename);
|
||
fflush (stderr);
|
||
perror (“getfile");
|
||
return (NULL);
|
||
}
|
||
|
||
/* get the memory to hold the table */
|
||
/* get size adding a byte for a trailing NUL */
|
||
*p_size = (unsigned) (fsize (file) + 1); /* byte for NUL end */
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 163 / Buchseite 153 ====
|
||
Irdb and C 153
|
||
|
||
}
|
||
|
||
/* get a buffer in memory for the system */
|
||
if ((filebuffer = malloc ((unsigned) *p_size)) == NULL) {
|
||
fprintf (stderr,
|
||
“Can't malloc the size of file %s.\n", filename);
|
||
fflush (stderr);
|
||
perror (“getfile");
|
||
return (NULL);
|
||
¥
|
||
|
||
/* read in the file and reset p_size to number of bytes read */
|
||
if ((*p_size = (unsigned) read (file, filebuffer, *p_size)) < 1) {
|
||
fprintf (stderr, “Can’t read file %s.\n", filename) ;
|
||
fflush (stderr) ;
|
||
perror ("getfile");
|
||
return (NULL);
|
||
}
|
||
|
||
/* write NULL at the end of the buffer */
|
||
*(filebuffer + *p_size) = NULL;
|
||
|
||
return (filebuffer) ;
|
||
|
||
getfile() calls fsize(), which gets the file size from the operating system via the system call
|
||
|
||
fstat():
|
||
|
||
/*
|
||
|
||
Copyright (c) 1990, 1991 Schaffer and Wright
|
||
fsize get the size of a file by calling the fstat routine
|
||
|
||
*/
|
||
#include "rdb.h"
|
||
#include <sys/types.h>
|
||
#include <sys/stat.h>
|
||
extern int Debug; /* global for debugging */
|
||
long fsize (file)
|
||
int file;
|
||
{
|
||
int fstat (); /* system call */
|
||
|
||
struct stat statusbuffer;/* info on file */
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 164 / Buchseite 154 ====
|
||
154 /rdb and C
|
||
|
||
/* get status information including size */
|
||
if ((fstat (file, &statusbuffer)) < 0) {
|
||
fprintf (stderr,
|
||
“fsize: Can’t get the size of file d\n", file);
|
||
perror ("fsize");
|
||
return (FAIL);
|
||
}
|
||
|
||
if (Debug)
|
||
fprintf (stderr, “fsize: file size=td\n",
|
||
statusbuffer.st_size);
|
||
|
||
/* return size */
|
||
return ((long) statusbuffer.st_size);
|
||
|
||
/rdb Functions: librdb.a
|
||
|
||
In the directory, $RDB/lib is the archive librdb.a, which contains all of the functions called
|
||
by the /rdb programs. You can call them like any function if you link the archive into your
|
||
program. For example, the command
|
||
|
||
cc -o prog prog.c librdb.a
|
||
|
||
compiles program. prog.c into executable prog, and links the contents of archive librdb.a
|
||
into the final executable.
|
||
|
||
If you. or your system administrator, moves the file to directory /usr/lib you only need to
|
||
add -Irdb to you compile line:
|
||
|
||
cc -o prog prog.c -lrdb
|
||
|
||
Colroutines
|
||
|
||
Another file in $RDB/lib is named Colroutines. “Col” stands for “column,” because the
|
||
functions largely handle the columns of a table. Colroutines contains documentation on
|
||
each of the C functions in librdb.a. It is the header of the source code for each routine. It
|
||
shows the description, function name, arguments and argument types. It should be enough
|
||
information to use the function, without being able to see the code.
|
||
|
||
Display Example
|
||
The example display.c calls the /rdb functions:
|
||
static char Copyright []="Copyright (c) 1990, 1991 Schaffer and Wright";
|
||
|
||
/*
|
||
|
||
display will read a table or list file and send to standard-out
|
||
*/
|
||
|
||
#define USAGE “usage: display < tableorlist\n"
|
||
|
||
#include “rdb.h"
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 165 / Buchseite 155 ====
|
||
/rdb andC 155
|
||
|
||
int Debug; /* global for debugging */
|
||
|
||
struct rowstruct row; /* row information */
|
||
|
||
int colgeth (), colgetr (); /* input functions */
|
||
int colputh (), colputr (); /* output functions */
|
||
int colinit (), coldump (); /* utility functions */
|
||
|
||
main (argc, argv, envp)
|
||
int argc;
|
||
|
||
char *argv [
|
||
char *envp [
|
||
|
||
{
|
||
|
||
l;
|
||
17
|
||
|
||
register columns; /* columns returned */
|
||
register i; /* index for loops */
|
||
|
||
/* handle command line arguments */
|
||
for (i = 1; i < argc; i++) {
|
||
if (argv [1][0] == ’-') {
|
||
switch (argv [1][1]) {
|
||
|
||
case 'D’:
|
||
if (argv [1][2] != Eos) {
|
||
Debug = atoi (&(argv [1][2]));
|
||
} else {
|
||
Debug = TRUE;
|
||
}
|
||
break;
|
||
/* add other options here */
|
||
|
||
default:
|
||
break;
|
||
}
|
||
} else {
|
||
|
||
/* get non-option arguments, like files, here */
|
||
}
|
||
}
|
||
|
||
/* get table or list headlines */
|
||
if ((columns = colgeth (&row)) == EOF)
|
||
exit (EOF);
|
||
|
||
/* output headlines */
|
||
colputh (&row);
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 166 / Buchseite 156 ====
|
||
156 /rdb and C
|
||
|
||
/* read in each row till end-of-file */
|
||
|
||
while ((columns = colgetr (&row)) I= EOF) {
|
||
/* output each row, or do other row processing */
|
||
colputr (&row);
|
||
|
||
}
|
||
|
||
/* return status code becomes shell $? variable for testing */
|
||
exit (OK);
|
||
}
|
||
|
||
Compile it with the command:
|
||
cc display.o -o display librdb.a
|
||
This assumes that lbrdb.a is in the current directory. If it is not, use its full path name.
|
||
When invoked with the command
|
||
display < inventory
|
||
display displays the following on the standard output:
|
||
Item Amount Cost Value Description
|
||
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
|
||
3 5 80 400 clamps
|
||
|
||
4 23 19 437 plates
|
||
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
Likewise, the command
|
||
display < maillist
|
||
displays the following on the standard output:
|
||
|
||
Number 1
|
||
|
||
Name Ronald McDonald
|
||
Company McDonald’s
|
||
Street 123 Mac Attack
|
||
|
||
City Menphis
|
||
|
||
State TENN
|
||
|
||
ZIP 30000
|
||
|
||
Phone (111) 222-3333
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 167 / Buchseite 157 ====
|
||
Irdb andC 157
|
||
|
||
Number 4
|
||
|
||
Name Chiquita Banana
|
||
|
||
Company United Brands
|
||
|
||
Street Uno Avenito De La Revolution
|
||
|
||
city San Jose
|
||
State Costa Rica
|
||
ZIP 123456789
|
||
|
||
Phone 1234
|
||
|
||
The first line is the copyright notice. It is declared to be a static char so that it will appear
|
||
in the object module and the binary code.
|
||
|
||
The next comment is a description of the purpose of the program. The USAGE definition
|
||
gives the syntax of the program. It can be displayed when a syntax error is detected. The
|
||
debugging system is described in the next section.
|
||
|
||
The row structure is defined in the rdb.h header file that can be included in your programs.
|
||
row contains lots of information about the headline and rows of the input table or list file.
|
||
It is passed to the various col functions, which are declared below row.
|
||
|
||
After main(), the command line arguments are handled. Only the Debug variable is set, but
|
||
this code can be edited to get all expected options and other arguments.
|
||
|
||
The col functions read in the headline and display it, followed by each row in the table or
|
||
list.
|
||
|
||
The return command returns an exit status so that the program can be tested with the
|
||
shells if, while, and for statements.
|
||
|
||
You can copy this program to start your own program. You can process each row of the
|
||
table as it is read in by inserting your code within the while loop. Have fun, but remember,
|
||
shell programming is much easier.
|
||
|
||
Debugging
|
||
The Debug variable is an external global variable that can be seen by all of the functions.
|
||
|
||
The advantage of this method of debugging is that it is in the final product so that
|
||
diagnostics can be run when errors are found by users and service people.
|
||
|
||
On the command line one can put -D to turn on debugging traces. These messages are
|
||
printed out as the program runs to show the value of certain key variables. To control the
|
||
quantity of output, one can follow the option with a number. The higher the number, the
|
||
more output. -D9 turns on all output, which is a lot to wade through. but shows
|
||
|
||
everything.
|
||
|
||
In the example below, all diagnostics are dumped. Each function gives its name and the
|
||
value of variables. colgeth( is the column-get-header function which calls colinit() to
|
||
initialize the row buffers.
|
||
|
||
The COHERENT function malloc() is invoked to get memory for head and row data. This is
|
||
part of the dynamic buffering that allows the programs to get as much memory as they can
|
||
to handle large heads and rows. In this way the /rdb programs are not limited by software.
|
||
but only by available hardware memory.
|
||
|
||
Because pointers are often a problem in C, several pointers are printed out. Their values
|
||
don't mean much, but can be checked to see that they have been set to reasonable
|
||
numbers. coldump lists all of the variables and their values in the row structure. You can
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 168 / Buchseite 158 ====
|
||
158 /rdb and C
|
||
|
||
also call coldump() from your program if you wish. (Of course, you can use the COHERENT
|
||
debugger db. if you prefer.)
|
||
|
||
colgetr() also displays the columns as they are read, so that you can see what it is seeing.
|
||
All of this is coming to you through the standard error (aka stderr), so that you can redirect
|
||
it. It is not buffered, so it comes out before the table which is coming through the buffered
|
||
standard output. and is not sent until the buffer is full or the stream is closed on program
|
||
termination.
|
||
|
||
The command
|
||
display -D9 < inventory
|
||
prints the following to the standard error:
|
||
|
||
colgeth: row=14976 filein=0
|
||
colinit: row=14976
|
||
colinit: bufsize=2048
|
||
colinit: colsize=2
|
||
colinit: p_buffer allocated
|
||
colinit: maxcolumns=1024
|
||
colinit: p_ heads allocated
|
||
colinit: p_ columns allocated
|
||
colinit: p_collengths allocated
|
||
coldump: ------------ aa aaa
|
||
|
||
row pointer
|
||
row=14976
|
||
|
||
file pointer for input file
|
||
row->p_filein=14754
|
||
|
||
fileout pointer for input fileout
|
||
row->p_fileout=0
|
||
|
||
points to buffer to write into
|
||
row->buf fer=16224
|
||
|
||
points to (offset) buffer to write into
|
||
row->p_buffer=16224
|
||
|
||
buffer size
|
||
row->bufsize=2048
|
||
|
||
points to end of buffer
|
||
row->p_endbuffer=18272
|
||
|
||
points to each head found in lists
|
||
row->p_heads=18274
|
||
|
||
to number of head columns found
|
||
row->heads=0
|
||
|
||
points to each column found
|
||
row->p_columns=20324
|
||
|
||
number of columns
|
||
row->columns=0
|
||
|
||
number of colsize
|
||
row->colsize=2
|
||
|
||
number of maxcolumns
|
||
row->maxcolumns=1024
|
||
|
||
each column’s length
|
||
row->collengths=22374
|
||
|
||
entire row length
|
||
row->rowlength=0
|
||
|
||
boolean fixed or variable
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 169 / Buchseite 159 ====
|
||
lrdb and C 159
|
||
|
||
row->fixed=0
|
||
boolean list or table
|
||
row->list=0
|
||
coldump: ---------------- een nn nnn <---
|
||
Item
|
||
Amount
|
||
Cost
|
||
Value
|
||
Description
|
||
colgetr: end-of-row.nrow->rowlength = 37
|
||
colgeth: row->heads=5
|
||
|
||
colgetr: end-of-row.nrow->rowlength = 37
|
||
colgeth: row->columns=5 length=38 fixed=0 list=0
|
||
colputh: row->p_fileout=0
|
||
1
|
||
3
|
||
50
|
||
150
|
||
rubber gloves
|
||
colgetr: end-of-row.nrow->rowlength = 36
|
||
2
|
||
100
|
||
5
|
||
500
|
||
test tubes
|
||
colgetr: end-of-row.nrow->rowlength = 33
|
||
3
|
||
}
|
||
80
|
||
400
|
||
clamps
|
||
colgetr: end-of-row.nrow->rowlength = 29
|
||
4
|
||
23.
|
||
19
|
||
437
|
||
plates
|
||
colgetr: end-of-row.nrow->rowlength = 29
|
||
5
|
||
99
|
||
24
|
||
2376
|
||
cleaning cloth
|
||
colgetr: end-of-row.nrow->rowlength = 37
|
||
6
|
||
89
|
||
147
|
||
13083
|
||
bunsen burners
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 170 / Buchseite 160 ====
|
||
160
|
||
|
||
/rdb and C
|
||
|
||
colgetr: end-of-row.nrow->rowlength = 37
|
||
7
|
||
5
|
||
175
|
||
875
|
||
scales
|
||
colgetr: end-of-row.nrow->rowlength = 29
|
||
colgetr: eof
|
||
Item Amount Cost Value Description
|
||
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
|
||
3 5 80 400 clamps
|
||
|
||
4 23 19 437 plates
|
||
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
We did warn you that there was a lot of it.
|
||
|
||
Fast-Access Example
|
||
|
||
The program inverted.c, found in directory $RDB/lib, demonstrates how to use the inverted
|
||
method from within a C program:
|
||
|
||
/* inverted.c is a sample program which illustrates the usage of the
|
||
fast access librdb.a routines (index and search).
|
||
specifically, this program exercises xinverted() and sinverted().
|
||
the search and index programs do essentially the same thing for
|
||
all fast access methods, and provide more command line options.
|
||
The following compile command assumes that the include file rdb.h and
|
||
library archive (distributed in the lib directory of rdb’s home dir)
|
||
are in the current directory: “cc -O inverted.c librdb.a -o xinverted"
|
||
Link the resulting xinverted binary to sinverted.nCall xinverted to
|
||
perform indexing and sinverted to perform searching.
|
||
|
||
&7/
|
||
|
||
char Copyright[] = "Copyright (c) 1990 by Schaffer and Wright";
|
||
|
||
/*
|
||
|
||
index index the given file according to the method specified.
|
||
It calls the xinverted (for index) routine.
|
||
|
||
search search the given file using the method specified.
|
||
It calls the sinverted (for search) routine.
|
||
|
||
*f,
|
||
|
||
#define USAGE “usage: %s [-n -x] tableorlist [keycolumn ...] [ < keytable ]\n"
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 171 / Buchseite 161 ====
|
||
/rdb andC 161
|
||
|
||
/*
|
||
|
||
-n = numeric comparison of key and column value
|
||
|
||
-x = partial match and upper or lower case insensitive
|
||
*/
|
||
|
||
#include “rdb.h"
|
||
int Debug; /* global for debugging */
|
||
char *Program; /* argv [0] program name */
|
||
|
||
char *Function = "main"; /* current function name */
|
||
|
||
/* error message table(make into include and automatic error handling) */
|
||
|
||
#define NOTABLE 1
|
||
#define EOPTION 2
|
||
#define NOMEM 3
|
||
#define NOFILENAME 4
|
||
#define NOFILE 5
|
||
#define NOPUT 6
|
||
#define NOKEYHEADS 7
|
||
|
||
/* structures */
|
||
|
||
struct rowstruct rowfile;
|
||
struct rowstruct rowkey;
|
||
struct keystruct key;
|
||
|
||
/* functions called */
|
||
int sinverted ();
|
||
int xinverted ();
|
||
|
||
int (*method) (); /* method function pointer */
|
||
|
||
/* comparison routines */
|
||
|
||
int colcmp (); /* default: ignore blanks */
|
||
|
||
int collook (); /* -x partial match, case insensitive */
|
||
int numemp (); /* =n numeric comparison */
|
||
|
||
int stremp (); /* -x exact character match */
|
||
|
||
/* flags */
|
||
|
||
int foldcase = FALSE; /* -x sort fold upper and lower case */
|
||
|
||
main (argc, argv, envp)
|
||
|
||
int argc;
|
||
char *argv :
|
||
char *envp [];
|
||
|
||
{
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 172 / Buchseite 162 ====
|
||
162 /rdb and C
|
||
|
||
TUTORIAL
|
||
|
||
register a; /* index for arguments */
|
||
|
||
register xe /* row found index */
|
||
|
||
char *p; /* character pointer */
|
||
|
||
int rows=0; /* number of rows matched */
|
||
int search=FALSE; /* search or index */
|
||
|
||
int matches; /* columns matched */
|
||
|
||
FILE *fopen (); /* functions used */
|
||
char *rindex();
|
||
|
||
/* get arguments */
|
||
if (Debug) fprintf (stderr, “argc=td\n", argc);
|
||
if (arge < 2) {
|
||
fprintf (stderr, USAGE, argv [0]);
|
||
exit (NOTABLE) ;
|
||
}
|
||
|
||
/* initialize key structure */
|
||
|
||
if (keyinit (&key) == FAIL)
|
||
exit (NOMEM) ;
|
||
|
||
key.singlerow = FALSE;
|
||
|
||
/* initialize rowkey structure */
|
||
if (colinit (&rowkey) == FAIL)
|
||
exit (NOMEM) ;
|
||
|
||
/* initialize: called by search or index */
|
||
|
||
/* handle path names, walk to end looking for slash */
|
||
if (p = rindex(argv[0], '/’)) ++p;
|
||
|
||
else p = argv[0];
|
||
|
||
/* if the command name begins with ’s’ assume search procedures */
|
||
|
||
if (*p == ‘'s‘)
|
||
search = TRUE; /* search */
|
||
else search = FALSE; /* index */
|
||
|
||
if (search)
|
||
method = sinverted;
|
||
else method = xinverted;
|
||
|
||
/* default comparison method is ignore blanks */
|
||
key.compare = colcmp;
|
||
|
||
/* loop through arguments looking for flags and file name */
|
||
for (a = 1; a < argc; att) {
|
||
if (Debug)
|
||
fprintf (stderr, "argv [%d]=%s\n", a, argv [a]);
|
||
|
||
==== PDF-Seite 173 / Buchseite 163 ====
|
||
lrdb and C 163
|
||
|
||
if (argv [aJ[0] == ‘-') {
|
||
switch (argv [a][1]) {
|
||
|
||
case ‘D’':
|
||
if (isdigit(argv [a][2]))
|
||
Debug = atoi (&argv [a][2]);
|
||
else Debug = TRUE;
|
||
|
||
break;
|
||
|
||
case ‘n’:
|
||
key.compare = numcmp;
|
||
break;
|
||
|
||
case ‘x’:
|
||
|
||
foldcase = TRUE;
|
||
key.compare = collook;
|
||
break;
|
||
|
||
default:
|
||
fprintf (stderr,
|
||
“$s: $s option not recognized\n",
|
||
argv [0], argv [a]);
|
||
fprintf (stderr, USAGE, argv [0]);
|
||
exit (EOPTION) ;
|
||
|
||
}
|
||
|
||
} else {
|
||
if (key.p_ filename == NULL) {
|
||
key.p_ filename = argv [a];
|
||
} else {
|
||
rowkey.p_heads [rowkey.heads++] = argv [a];
|
||
|
||
}
|
||
|
||
/* do we have a file to open */
|
||
if (key.p_filename == NULL) {
|
||
|
||
fprintf (stderr, “ts: no file name\n", argv [0]);
|
||
fprintf (stderr, USAGE, argv [0]);
|
||
exit (NOFILENAME) ;
|
||
|
||
/* open the file */
|
||
key.file = rowfile.p filein = fopen (key.p filename, READ);
|
||
|
||
rowfile.p fileout = stdout;
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 174 / Buchseite 164 ====
|
||
164 /rdb and C
|
||
|
||
TUTORIAL
|
||
|
||
if (rowfile.p filein == NULL) {
|
||
fprintf (stderr,
|
||
"$s: Can not open %s\n", argv [0], key.p_ filename) ;
|
||
|
||
exit (NOFILE);
|
||
|
||
if (Debug)
|
||
fprintf (stderr, "%s: rowfile.columns=%d\n",
|
||
argv [0], rowfile.columns) ;
|
||
|
||
/* get the head line of the file */
|
||
if ((rowfile.columns = colgeth (&rowfile)) == EOF)
|
||
exit (EOF);
|
||
|
||
if (Debug)
|
||
fprintf (stderr, “ts: rowfile.columns=%d\n",
|
||
argv [0], rowfile.columns) ;
|
||
|
||
/* put the head line of the file */
|
||
if (search) {
|
||
if (colputh (&rowfile) == FAIL)
|
||
exit (NOPUT);
|
||
}
|
||
|
||
/* if the key columns are not in the command line,
|
||
get from the stdin */
|
||
|
||
rowkey.p filein = stdin;
|
||
|
||
rowkey.p fileout = stdout;
|
||
|
||
if (rowkey.heads == 0) {
|
||
/* get from key head */
|
||
if ((rowkey.heads = colgeth (&rowkey)) == EOF)
|
||
exit (EOF);
|
||
|
||
}
|
||
|
||
/* get first row if list */
|
||
if (rowfile.list)
|
||
if ((rowfile.columns = colgetr (&rowfile)) == EOF)
|
||
exit (EOF);
|
||
|
||
if (rowkey.list)
|
||
if ((rowkey.columns = colgetr (&rowkey)) == EOF)
|
||
exit (EOF);
|
||
|
||
==== PDF-Seite 175 / Buchseite 165 ====
|
||
lrdb andC 165
|
||
|
||
/* find key columns in the file columns */
|
||
matches = colmatch (rowfile.p heads, rowfile.heads,
|
||
rowkey.p_ heads, rowkey.heads, key.keytocolumn) ;
|
||
|
||
if (matches != rowkey.heads) {
|
||
fprintf (stderr,
|
||
"%s: Can not find your keys in column heads.\n",
|
||
argv [0]);
|
||
|
||
exit (NOKEYHEADS) ;
|
||
}
|
||
|
||
/* if index, go and index and then exit */
|
||
if (1! search) {
|
||
if (Debug) fprintf (stderr,
|
||
“ts: rowfile.p filein=%d\n", argv [0], rowfile.p filein) ;
|
||
|
||
/* call method */
|
||
if ((rows = (*method) (&key, &rowfile, &rowkey)) < 0) {
|
||
perror (argv [0]);
|
||
exit (rows);
|
||
}
|
||
exit (OK);
|
||
}
|
||
|
||
/* get first row of keys if table */
|
||
if (Debug) {
|
||
fprintf (stderr, "ts: before colgetr (&rowkey)\n",
|
||
argv [0]);
|
||
colputh (&rowkey) ;
|
||
}
|
||
|
||
if (rowkey.list == FALSE)
|
||
if ((rowkey.columns = colgetr (&rowkey)) == EOF)
|
||
exit (NOKEYHEADS) ;
|
||
|
||
if (Debug) {
|
||
fprintf (stderr,
|
||
“$s: after colgetr (&rowkey)\n", argv [0]);
|
||
colputh (&rowkey) ;
|
||
colputr (&rowkey);
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 176 / Buchseite 166 ====
|
||
166 /rdb and C
|
||
|
||
/* loop getting key(s) from stdin */
|
||
|
||
do {
|
||
if (Debug) {
|
||
fprintf (stderr,
|
||
“$s: Before method rowkey.columns=%d\n",
|
||
argv[0], rowkey.columns) ;
|
||
}
|
||
/* don’t look if no keys */
|
||
if (rowkey.columns == 0)
|
||
continue;
|
||
/* call method */
|
||
rows = (*method) (&key, &rowfile, &rowkey) ;
|
||
if (Debug) fprintf (stderr,
|
||
“@st After method rows=%d key.rowoffsets [0]=%d\n",
|
||
argv[0], rows, key.rowoffsets [0]);
|
||
if (rows <= 0) {
|
||
continue;
|
||
}
|
||
for (xr = 0; r < rows; r++) {
|
||
if (fseek (rowfile.p filein,
|
||
key.rowoffsets [r], BEGINNING)
|
||
== BADSEEK)
|
||
fprintf (stderr, “search: Bad seek.\n");
|
||
colgetr (&rowfile);
|
||
colputr (&rowfile);
|
||
}
|
||
}
|
||
|
||
while ((rowkey.columns = colgetr (&rowkey)) != EOF);
|
||
|
||
exit (OK);
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 177 / Buchseite 167 ====
|
||
Section 17:
|
||
|
||
Manual Pages
|
||
|
||
The following gives manual pages for all /rdb commands. These include the commands
|
||
used by the /act accounting system, which is included as an example of /rdb
|
||
programming.
|
||
|
||
167
|
||
|
||
==== PDF-Seite 178 / Buchseite 168 ====
|
||
168
|
||
|
||
TUTORIAL
|
||
|
||
==== PDF-Seite 179 / Buchseite 169 ====
|
||
accounting terms 169
|
||
|
||
A
|
||
|
||
accounting terms — Definition
|
||
The following defines several of the more commonly used accounting terms. These are
|
||
included to help you understand the descriptions of /rdb's accounting package.
|
||
|
||
Financial information that records the day-to-day operation of a business is recorded in an
|
||
account. A simple account is made up of three parts:
|
||
|
||
1. A title that describes the name of the information being stored in the account;
|
||
2. The left side of the account, used to record a debit; and
|
||
3. The right side of the account, used to record a credit.
|
||
|
||
This simple configuration is referred to as a ‘T’ account because its shape resembles a
|
||
capital T:
|
||
|
||
Title
|
||
|
||
Debit | Credit
|
||
|
||
A ledger is the combination of all the accounts maintained by a business. Transactions are
|
||
posted to accounts through a journal entry, as in the following example:
|
||
|
||
Cash | 500.00 |
|
||
Sales | | 500.00
|
||
|
||
Entries recorded on the far left are debits; entries indented from the left are credits.
|
||
Accounts fall into the following classifications:
|
||
Assets Anything that is owned and has a monetary value.
|
||
|
||
Liabilities
|
||
Amounts owed to others.
|
||
|
||
Capital This is the owner's equity in the business. It is equal to the total assets minus the
|
||
total liabilities.
|
||
|
||
Revenue
|
||
Proceeds obtained in the course of doing business.
|
||
|
||
Expenses
|
||
Costs incurred in the course of doing business.
|
||
|
||
Further information on accounting terms may be obtained from any textbook on accounting
|
||
principles. Your local public library should contain several examples.
|
||
|
||
See Also
|
||
act
|
||
|
||
Notes
|
||
|
||
Please note that /rdb's accounting system is meant to serve as an example of data-base
|
||
programming with /rdb. It is not designed to be an exhaustive accounting package. nor is it
|
||
designed to teach you how to perform accounting. Mark Williams technical support will
|
||
help you if you have a problem with an /rdb command, but not with problems that involve
|
||
the principles of accounting. Caveat utilitor.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 180 / Buchseite 170 ====
|
||
170 act — addcol
|
||
|
||
act — /rdb Command
|
||
List all /act commands
|
||
act
|
||
|
||
/rdb comes with a set of commands that implement a basic accounting system, suitable for
|
||
running a small business. These commands, called /act commands, are kept in directory
|
||
SRDB/act.
|
||
|
||
The accounting system consists of the following sub-systems:
|
||
gl General ledger
|
||
|
||
inv Inventory
|
||
|
||
opr Operations, for manufacturing
|
||
|
||
pay Payroll
|
||
|
||
pur Accounts payable and purchasing
|
||
|
||
sales
|
||
Accounts payable and sales
|
||
|
||
The command act lists all /act commands.
|
||
|
||
Example
|
||
Typing act displaying the following on your screen:
|
||
|
||
act close income postap shorttoaccount
|
||
adjust consolidate invoice postar start
|
||
|
||
balance cstate makecatalog postpay tax.calc
|
||
|
||
bom fillform onhand purchase trial
|
||
calculate foot po sale vstate
|
||
chartdup getjournal post ship w2
|
||
|
||
Many act commands have their own entries in this manual.
|
||
|
||
See Also
|
||
|
||
accounting terms
|
||
|
||
Notes
|
||
|
||
Please note that /rdb’s accounting system is meant to serve as an example of data-base
|
||
programming with /rdb. It is not designed to be an exhaustive accounting package, nor is it
|
||
designed to teach you how to perform accounting. Mark Williams technical support will
|
||
help you if you have a problem with an /rdb command, but not with problems that involve
|
||
the principles of accounting. Caveat utilitor.
|
||
|
||
addcol — /rdb Command
|
||
|
||
Add a column to a table
|
||
addcol newcolumn < table
|
||
|
||
The command addcol appends one or more new columns to table. The column is initialized
|
||
to blank spaces, and is given the name newcolumn.
|
||
|
||
Example
|
||
|
||
The command
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 181 / Buchseite 171 ====
|
||
addcol New < inventory
|
||
|
||
modifies table inventory to appear as follows:
|
||
|
||
Item Amount Cost Value Description New
|
||
|
||
1 3 50 150 rubber gloves
|
||
|
||
2 100 5 500 test tubes
|
||
|
||
3 5 80 400 clamps
|
||
|
||
4 23 19 437 plates
|
||
|
||
5 99 24 2376 cleaning cloth
|
||
|
||
6 89 147 13083 bunsen burners
|
||
|
||
7 5 175 875 scales
|
||
|
||
Note that column New has been added to the table.
|
||
|
||
See Also
|
||
jointable, number
|
||
|
||
adjust — /act/gl Command
|
||
Create adjusted trial balance table
|
||
adjust
|
||
|
||
The command adjust is part of the accounting/ general ledger system that is included with
|
||
/rdb. It produces the adjusted trial balance sheet, called adjusttrial, by adding the trial-
|
||
balance table trialbalance with the journal-of-adjustments table journaladjust.
|
||
|
||
The accountant makes adjustments at the end of the accounting period, to reflect changes
|
||
in inventory, depreciation, depletion, amortization, and so on. These are computed costs of
|
||
doing business that are assigned to each accounting period.
|
||
|
||
Example
|
||
|
||
The following gives an example of table trialbalance:
|
||
|
||
Account Debit Credit Format Taxline Short Name
|
||
|
||
1010 11178 B-A 4L01 cash Cash
|
||
|
||
3010 13500 I-I 10la sales Sales
|
||
|
||
3080 250 I-I 106 royalty Gross royalties
|
||
3100 3286 I-I 108 income Other Income
|
||
4020 3601 I-COGS 102-A2 merch Misc Merchandise
|
||
4030 2100 I-cOGS 102-A3 wages Salary and Wages
|
||
4370 2 I-E 122 parking Business parking
|
||
4380 41 I-E 122 travel Business travel
|
||
4384 114 I-E 122 hotel Business hotel
|
||
|
||
The following gives an example of table journaladjust:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 182 / Buchseite 172 ====
|
||
172 append
|
||
|
||
Account Debit
|
||
|
||
1310
|
||
1330
|
||
1420
|
||
4010 20000
|
||
4080
|
||
4170 i)
|
||
4180 0
|
||
4215 0
|
||
|
||
Credit
|
||
|
||
Format Taxline Name
|
||
|
||
B-A
|
||
B-A
|
||
B-A
|
||
I-coGs
|
||
I-coGs
|
||
I-E
|
||
I-E
|
||
I-E
|
||
|
||
4L12a
|
||
102-Al
|
||
102-A4
|
||
121
|
||
118
|
||
122
|
||
|
||
Beginning Inventory
|
||
Ending Inventory
|
||
Accum Depreciation
|
||
Accum Depletion
|
||
Accum Amortization
|
||
Beginning Inventory
|
||
Ending Inventory
|
||
Depreciation
|
||
Depletion
|
||
Amortization
|
||
|
||
The command adjust then produces the table adjustedtrial by combining trialbalance with
|
||
journaladjust. In this example, adjustedtrial appears as follows:
|
||
|
||
Account Debit
|
||
|
||
1110 2130
|
||
1310 0
|
||
1330 0
|
||
1420 t)
|
||
3010
|
||
|
||
3080
|
||
|
||
3100
|
||
|
||
4010 20000
|
||
4020 3601
|
||
4030 2100
|
||
4080
|
||
|
||
4170 0
|
||
4180 to}
|
||
4215 ()
|
||
4370 2
|
||
4380 41
|
||
4384 114
|
||
See Also
|
||
|
||
act, balance
|
||
|
||
append — /rdb Command
|
||
|
||
Credit
|
||
|
||
13500
|
||
250
|
||
3286
|
||
|
||
22130
|
||
|
||
Format Taxline Short
|
||
|
||
Add a row to a table and update index tables
|
||
append [-h -m[bhirs]] table [keycolumn ...] < tableorrow
|
||
|
||
inv
|
||
adeprec
|
||
adeplet
|
||
aamort
|
||
sales
|
||
royalty
|
||
income
|
||
beginv
|
||
merch
|
||
wages
|
||
endinv
|
||
deprec
|
||
deplet
|
||
amor
|
||
parking
|
||
travel
|
||
hotel
|
||
|
||
Cash
|
||
|
||
Inventory
|
||
|
||
Accum Depreciation
|
||
Accum Depletion
|
||
Accum Amortization
|
||
Sales
|
||
|
||
Gross royalties
|
||
Other Income
|
||
|
||
Begin Inventory
|
||
Misc Merchandise
|
||
Salary and Wages
|
||
Ending Inventory
|
||
Depreciation
|
||
Depletion
|
||
Amortization
|
||
Business parking
|
||
Business travel
|
||
Business hotel
|
||
|
||
The command append appends the row in table tableorrow onto the end of table. It also
|
||
updates the appropriate index table so that the next search will find it. For the record
|
||
method of indexing, append adds the new record's offset to the end of the index table. For
|
||
the inverted method of indexing, it adds the record and then sorts the table.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 183 / Buchseite 173 ====
|
||
append 173
|
||
|
||
Options
|
||
|
||
append recognizes the following options:
|
||
|
||
-h tableorrow has no /rdb head line and dash line. This option is useful when you
|
||
only have a row to append to a table, but it does not have a head line.
|
||
|
||
-m{bhirs]
|
||
Use a fast-access method. See the manual page for search for a description of the
|
||
fast-access methods and how to invoke them.
|
||
|
||
Example
|
||
Consider the table inventory, which is defined as follows:
|
||
|
||
Item Amount Cost Value Description
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
3 5 80 400 clamps
|
||
4 23 19 437 plates
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
This table has an index table, called record, which appears as follows:
|
||
Offset
|
||
|
||
76
|
||
113
|
||
147
|
||
177
|
||
207
|
||
245
|
||
283
|
||
|
||
Finally, consider the table newrecord, which is as follows:
|
||
Item Amount Cost Value Description
|
||
|
||
8 35 105 0 pipettes
|
||
|
||
Note that newrecord has the same columnar layout as inventory.
|
||
The following command appends newrecord onto the end of inventory:
|
||
append -mr inventory < newrecord
|
||
|
||
After append has done its work, inventory appears as follows:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 184 / Buchseite 174 ====
|
||
174
|
||
|
||
ascii
|
||
|
||
Item Amount
|
||
|
||
99
|
||
89
|
||
|
||
5
|
||
35
|
||
|
||
DIAKDUPWNHHR
|
||
|
||
inventory’s index table now appears as follows:
|
||
|
||
Offset
|
||
76
|
||
|
||
113
|
||
147
|
||
177
|
||
207
|
||
245
|
||
283
|
||
313
|
||
|
||
The new “313” entry in the secondary index table inventory.r is the offset to record 8 —
|
||
|
||
a9
|
||
24
|
||
147
|
||
175
|
||
105
|
||
|
||
2376
|
||
13083
|
||
875
|
||
|
||
i)
|
||
|
||
Description
|
||
rubber gloves
|
||
test tubes
|
||
clamps
|
||
|
||
plates
|
||
cleaning cloth
|
||
bunsen burners
|
||
scales
|
||
pipettes
|
||
|
||
that is, the number of bytes for the beginning of the file to record 8.
|
||
|
||
See Also
|
||
|
||
delete, index, replace, search
|
||
|
||
ascii — /rdb Command
|
||
Return the ASCII value of a character
|
||
|
||
ascii character...
|
||
|
||
The command ascii converts each of the characters in its first argument to a space-
|
||
delimited series of numbers. You can use this command to find the internal computer
|
||
representation of a character. Any strings following the first are ignored. If you have spaces
|
||
|
||
in your string, be sure to put quotation marks around them.
|
||
|
||
Example
|
||
|
||
The command
|
||
ascii aAl
|
||
produces:
|
||
97 65 49
|
||
The command
|
||
ascii’ '
|
||
produces:
|
||
32
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 185 / Buchseite 175 ====
|
||
ascii 175
|
||
|
||
Note that the single space character, enclosed within apostrophes, is converted to its ASCII
|
||
code in decimal (32).
|
||
|
||
See Also
|
||
|
||
chr
|
||
COHERENT Lexicon: ASCII
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 186 / Buchseite 176 ====
|
||
176 backup — balance
|
||
|
||
backup — Technical Information
|
||
When you are using /rdb to store and manipulate your data, you must back up your data
|
||
regularly. If you do not back up your data and your disk should fail for whatever reason.
|
||
your data will be irretrievably lost.
|
||
|
||
See the COHERENT manual section 2, Using the COHERENT System, for a detailed
|
||
description of how to back up your data. Also see the Lexicon articles on ustar and cpio for
|
||
descriptions of how to use these tools to back up your data.
|
||
|
||
balance — /act/gl Command
|
||
Create balance sheet from adjusted trial balance
|
||
balance
|
||
|
||
The command balance is part of the accounting/general-ledger system included with /rdb.
|
||
It reads table adjustedtrial and writes a balance sheet into table and writes it into file
|
||
|
||
balancesheet.
|
||
|
||
Example
|
||
|
||
Consider the table adjustedtrial, as follows:
|
||
|
||
Account Debit Credit Format Taxline Short Name
|
||
|
||
1010 11178 B-A 4L01 cash Cash
|
||
|
||
1110 2130 B-A 4L06 inv Inventory
|
||
|
||
1310 0 B-A 4L09a adeprec Accum Depreciation
|
||
1330 0 B-A 4L10a adeplet Accum Depletion
|
||
1420 0 B-A 4L12a aamort Accum Amortization
|
||
3010 13500 I-I 10la sales Sales
|
||
|
||
3080 250 I-1 106 royalty Gross royalties
|
||
3100 3286 I-I 108 income Other Income
|
||
4010 20000 I-COGS 102-Al beginv Begin Inventory
|
||
4020 3601 I-cOGS 102-A2 merch Misc Merchandise
|
||
4030 2100 I-COGS 102-A3 wages Salary and Wages
|
||
4080 22130 I-COGS 102-A4 endinv Ending Inventory
|
||
4170 0 I-E 121 deprec Depreciation
|
||
4180 0 I-E 118 deplet Depletion
|
||
|
||
4215 i) I-E 122 amor Amortization
|
||
4370 2 I-E 122 parking Business parking
|
||
4380 41 I-E 122 travel Business travel
|
||
4384 114 I-E 122 hotel Business hotel
|
||
|
||
The command balance writes the balance sheet into balancesheet, which appears as
|
||
follows:
|
||
|
||
Makeapile, Inc.
|
||
31 December 1985
|
||
Balancesheet
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 187 / Buchseite 177 ====
|
||
blank 177
|
||
|
||
11178 Cash
|
||
|
||
2130 Inventory
|
||
t) Accumulated Depreciation
|
||
te) Accumulated Depletion
|
||
i) Accumulated Amortization
|
||
|
||
13308 Total Assets
|
||
|
||
13308 Retained Earnings (Profit)
|
||
|
||
13308 Total Liabilities and Equity
|
||
|
||
See Also
|
||
|
||
act, adjust
|
||
|
||
blank — /rdb Command
|
||
|
||
Replace all data in a record with spaces
|
||
blank < tableorlist
|
||
|
||
The command blank replaces with spaces every values in each record of tableorlist.
|
||
|
||
The command update uses blank when it updates a record. update temporarily replaces
|
||
the record it is updating with a blank record. This blank record serves as a record lock; this
|
||
ensures that other users cannot read or update the record while it is being updated, but it
|
||
leaves the rest of the table available for use.
|
||
|
||
Please note that when you pull up a blank record, it means that that record is being
|
||
updated by someone else. Come back to it later.
|
||
|
||
Example
|
||
To blank out the data fields in table maillist and then see the result. you could type the
|
||
following:
|
||
|
||
blank < maillist | see
|
||
This command produces the following output:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 188 / Buchseite 178 ====
|
||
178 bom
|
||
|
||
Number“I $
|
||
|
||
Name“*I $
|
||
Company “*I $
|
||
Street *I $
|
||
city*I $
|
||
|
||
State*I $
|
||
|
||
ZIP*I $
|
||
|
||
Phone*I $
|
||
$
|
||
|
||
Number“I $
|
||
|
||
Name*I $
|
||
Company*I $
|
||
Street *I $
|
||
City*I $
|
||
|
||
State*I $
|
||
ZIP*I $
|
||
|
||
Phone*I $
|
||
|
||
Note the spaces between the tab (*I) and the dollar sign ‘8’ that indicates the end of the line.
|
||
The spaces replaced the characters, including spaces, that were in the original records.
|
||
|
||
Note too that the column names are untouched, so that this is a perfectly correct file as far
|
||
as the /rdb commands are concerned. it just contains no data.
|
||
|
||
See Also
|
||
|
||
see, update
|
||
|
||
bom — /act/opr Command
|
||
Produce bill-of-materials from parts list
|
||
bom
|
||
|
||
The command bom is part of the accounting/operations system included with /rdb. It
|
||
creates a bill-of-materials table from table part, which holds all of the items that are
|
||
required to make a product, and the table saleitem, which holds all sales items from the
|
||
sales department. This tells how many items must be manufactured or purchased to meet
|
||
current sales orders.
|
||
|
||
bom writes its output into table bom.
|
||
|
||
Example
|
||
Assume the table saleitem contains the following data:
|
||
|
||
Order Number Code Backord Qty Price Total Name
|
||
|
||
1 1 rdb 10 1 1500 1500.00 /rdb
|
||
2 1 rdb 10 2 1500 3000.00 /rdb
|
||
3 1 rdb 10 5 1500 7500.00 /rdb
|
||
3 2 act 10 10 1500 15000.00 /act
|
||
4 1 rdb 10 5 1500 7500.00 /rdb
|
||
4 2 rdb 10 19 1500 28500.00 /rdb
|
||
5 Fs rdb 10 5 1500 7500.00 /rdb
|
||
5 2 act 10 9 1500 13500.00 /act
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 189 / Buchseite 179 ====
|
||
bom 179
|
||
|
||
Assume, too, that the table part contains the following data:
|
||
Code Subpart Count
|
||
|
||
act binder 2
|
||
act actdoc 2
|
||
act f1 10
|
||
rdb binder 2
|
||
rdb rdbdoc 2
|
||
rdb fl 10
|
||
|
||
Code Qty
|
||
|
||
actdoc 38
|
||
binder 112
|
||
fl 560
|
||
rdbdoc 74
|
||
|
||
You can see that we have orders for 19 copies of acts in the salesitem table. Each package
|
||
has two documents, for a total of 38 actdocs. Note that table bom lists 560 floppies ((19 act
|
||
x 10) + (37 rdb x 10)). We can order these, regardless oi which software packages are being
|
||
put onto them.
|
||
|
||
See Also
|
||
|
||
act
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 190 / Buchseite 180 ====
|
||
180 calcpay — cap
|
||
|
||
calcpay — /act/pay Command
|
||
|
||
Post payroll to ledgerpay
|
||
calcpay
|
||
|
||
The command calcpay is part of the accounting/ payroll system that is included with /rdb.
|
||
It posts the payroll-journal table Journalpay to the payroll-ledger table ledgerpay. This
|
||
ledger groups the pay checks by employee, and is used to create the W2 form.
|
||
|
||
Example
|
||
|
||
Assume that table journalpay has the following data:
|
||
|
||
Date Number Hours Salary Rate Gross Federal State Net
|
||
|
||
860518 1 80 1000 0 1000 70 10 920
|
||
860518 2 80 ) 10 800 42 6 752
|
||
860518 3 30 0 10 300 0 0 300
|
||
|
||
Typing calcpay copies it to table calcpay.
|
||
|
||
See Also
|
||
act, getjournal
|
||
|
||
calculate — /act/gl Command
|
||
|
||
Compute each tax form listed
|
||
calculate taxform...
|
||
|
||
The command calculate is part of the accounting/general-ledger system that is included
|
||
with /rdb. It is a simple shell script that calculates each tax form listed on its command
|
||
line.
|
||
|
||
Example
|
||
|
||
The following command calculates the IRS 1040 form
|
||
calculate 1040
|
||
|
||
See Also
|
||
|
||
act, filiform
|
||
|
||
Notes
|
||
|
||
Please note that the tax tables included with /rdb are from 1987. They are included solely
|
||
to serve as examples, and no claim is made as to their accuracy when calculating current
|
||
taxes. Caveat utilitor.
|
||
|
||
cap — /rdb Command
|
||
Convert first letter of each word to upper case
|
||
cap < textfile
|
||
|
||
The command cap capitalizes the first letter of each word in textfile. It writes its results to
|
||
the standard output.
|
||
|
||
Example
|
||
Assume that table Inventory has the following data:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 191 / Buchseite 181 ====
|
||
cashflow 181
|
||
|
||
Item Amount Cost Value Description
|
||
|
||
1 =} 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
|
||
3 5 80 400 clamps
|
||
|
||
4 23 19 437 plates
|
||
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
As you can see, the column Descriptions has consists of words all in lower case. To
|
||
capitalize the first letter of each word in Inventory file, type:
|
||
|
||
cap < Inventory
|
||
|
||
This writes the following on the screen:
|
||
|
||
Item Amount Cost ValueDescription
|
||
1 3 50 150 Rubber Gloves
|
||
2 100 5 500Test Tubes
|
||
3 5 80 400Clamps
|
||
4 23 19 437 Plates
|
||
5 99 24 2376Cleaning Cloth
|
||
6 89 147 13083Bunsen Burners
|
||
7: 5 175 875 Scales
|
||
|
||
See Also
|
||
|
||
lowercase, uppercase
|
||
|
||
cashflow — /rdb Command
|
||
Compute balance column of cash table
|
||
cashflow < cashtable
|
||
|
||
The command cashflow helps you manage your cash flow. It reads cashtable, which you
|
||
design, then computes a running balance in a Balance column (which must be column 3)
|
||
from an Amount column (which must be column 2).
|
||
|
||
Cash-flow analysis lets you see if you will always have enough money in hand to cover each
|
||
day's bills. It makes cash management possible by telling you whether to put off an
|
||
expense until a check arrives, ask for an advance, get to work and make more money, or
|
||
|
||
control your spending.
|
||
Example
|
||
|
||
The following gives an example cashtable, called cash:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 192 / Buchseite 182 ====
|
||
182
|
||
|
||
cashflow
|
||
|
||
Date Amount Balance Description
|
||
890101 512 current balance
|
||
890101 -450 rent check
|
||
890101 1000 pay check
|
||
890115 -300 estimated tax payment
|
||
890115 1000 pay check
|
||
890115 -1000 living expenses
|
||
890120 -900 big purchase
|
||
890201 1000 pay check
|
||
890201 -450 rent check
|
||
890215 1000 pay check
|
||
890115 -1000 living expenses
|
||
|
||
The command cashflow needs two columns, named Amount and Balance. (If you use
|
||
different column names, you must edit the cashflow shell script). All other columns are
|
||
optional. Each row in your table represents a projected income item (positive) or a projected
|
||
expense (negative). This is your flow of cash. To summarize the cash flow in our example
|
||
table cash, type:
|
||
|
||
cashflow < cash
|
||
|
||
This prints the following on your screen:
|
||
|
||
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
|
||
890115 1000 1762 pay check
|
||
890115 -1000 762 living expenses
|
||
890120 -900 -138 big purchase
|
||
890201 1000 862 pay check
|
||
890201 -450 412 rent check
|
||
890215 1000 1412 pay check
|
||
890115 -1000 412 living expenses
|
||
|
||
That big purchase gives us a negative balance in 890120. Now that you know, you can do
|
||
something about it. One move is to put the big purchase off until the first of February.
|
||
After you edit table cash to reflect this change. it appears as follows:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 193 / Buchseite 183 ====
|
||
cashflow 183
|
||
|
||
Date Amount Balance Description
|
||
890101 512 current balance
|
||
890101 -450 rent check
|
||
890101 1000 pay check
|
||
890115 -300 estimated tax payment
|
||
890115 1000 pay check
|
||
890115 -1000 living expenses
|
||
890201 1000 pay check
|
||
890201 -900 big purchase
|
||
890201 -450 rent check
|
||
890215 1000 pay check
|
||
890115 -1000 living expenses
|
||
|
||
Running cashflow again will tell us if this strategy works:
|
||
|
||
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
|
||
890115 1000 1762 pay check
|
||
890115 -1000 762 living expenses
|
||
890201 1000 1762. ~—-pay check
|
||
890201 -900 862 big purchase
|
||
890201 -450 412 rent check
|
||
890215 1000 1412 pay check
|
||
890115 -1000 412 living expenses
|
||
|
||
As you can see, this works — there's no negative cash flow for any period. You can also try
|
||
other options.
|
||
|
||
You can do all of the inputting and editing in the text editor. You can execute commands in
|
||
vi by using the exclamation ‘!’ shell feature; or from MicroEMACS by typing <ctrl-X>!. You
|
||
also might want to write out to a tmp file and use mv to overwrite your cash table so that it
|
||
is file is up to date. For example, in vi you can type:
|
||
|
||
:!cashflow < cashtable > tmp ; mv tmp cashtable
|
||
|
||
sel
|
||
The first line computes the Balance column, writes the result into a tmp file, and moves
|
||
tmp to be the new cashtable. All of this is necessary because in COHERENT you cannot
|
||
have one file as both input and output without wiping out the file. The second line, :e!
|
||
pulls the new file into the vi editor and displays it on your screen.
|
||
See Also
|
||
COHERENT Lexicon: ksh, me, sh, vi
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 194 / Buchseite 184 ====
|
||
184 chartdup — check.rdb
|
||
|
||
chartdup — /act/gl Command
|
||
|
||
Check for duplicate names and accounts in chart
|
||
|
||
chartdup
|
||
|
||
The command chartdup is part of the accounting/general-ledger system that is included
|
||
with /rdb. It checks to see if there are any duplicates among the account numbers or the
|
||
short names within the chart of accounts. This is the most common error that people make
|
||
|
||
when they update the chart of accounts.
|
||
|
||
Example
|
||
|
||
The following gives example output of chartdup:
|
||
|
||
Duplicate Account numbers in chart.
|
||
|
||
4150 I-E 115 taxes
|
||
4150 I-E BE BS taxes
|
||
Duplicate Short names in chart.
|
||
4150 I-E 115 taxes
|
||
4150 I-E 115 taxes
|
||
|
||
check.rdb — /rdb Command
|
||
|
||
See chart.Account
|
||
Taxes
|
||
|
||
Taxes
|
||
|
||
See chart.Short
|
||
|
||
Taxes
|
||
|
||
Taxes
|
||
|
||
Report any rows in which columns do not match head line
|
||
|
||
check.rdb < tableorlist
|
||
|
||
The command check.rdb counts the columns (number of tabs plus one) in the head line of
|
||
an /rdb table or list formatted file. Then it displays information on each row that does not
|
||
match the number of columns in the first head-line row. You should use it to see if your
|
||
data entry is correct. If your head-line row is incorrect, then all of your rows will be
|
||
|
||
reported as errors.
|
||
|
||
check.rdb returns zero when all is correct, and nonzero when it has found an error. You
|
||
can use this status value ($?) in a shell script to take different actions, depending upon the
|
||
|
||
validity of the table or list file.
|
||
|
||
Examples
|
||
Here is a bad table, called badtable:
|
||
|
||
Date Account Debit Credit
|
||
820102 101 25000
|
||
820102 211.1 25000
|
||
820103 150.1 10000
|
||
820103 101 5000
|
||
820103 211.2 5000
|
||
820104 130 30000
|
||
820104 201.1 15000
|
||
820104 101 15000
|
||
|
||
It is hard to see anything wrong with it.
|
||
|
||
check.rdb < badtable
|
||
|
||
we see the following output:
|
||
|
||
LEXICON
|
||
|
||
Description
|
||
|
||
cash from loan
|
||
|
||
loan #378-14 Bank Amerigold
|
||
test equipment from Zarkoff
|
||
cash payment
|
||
|
||
note payable to Zarkoff
|
||
inventory - parts from CCPSC
|
||
accounts payable to CCPSC
|
||
|
||
cash payment to CCPSC for parts
|
||
|
||
However, when we run the command
|
||
|
||
==== PDF-Seite 195 / Buchseite 185 ====
|
||
check.rdb 185
|
||
|
||
check.rdb: Columns (4) do not equal headline columns (5) in row 3 (line 5).
|
||
820103 150.1 10000 test equipment from Zarkoff
|
||
|
||
The command
|
||
see < badtable
|
||
gives us the following output:
|
||
|
||
Date*IAccount *IDebit *ICredit *IDescription$
|
||
|
||
----*I ------ “I----- “I ------ *----------- $
|
||
820102*1101*125000*I*Icash from loan$
|
||
820102*1211.1*1I*125000*Iloan number #378-14 Bank Amerigold$
|
||
820103*1I150.1 10000*I*Itest equipment from Zarkoff$
|
||
820103*1101*I*1I5000*Icash payment$
|
||
820103*I211.2*1I*1I5000*Inote payable to Zarkoff Equipment$
|
||
820104*1I130*1I30000*I*Iinventory - parts from CCPSC$
|
||
820104*1201.1*I*115000*Iaccounts payable to CCPSC*I$
|
||
820104*I101*I15000*I*Icash payment to CCPSC for parts$
|
||
|
||
Note that a tab is missing from row 3 (line 5) of badtable, between values 150.1 and 10000.
|
||
The spaces hide the fact that it is missing.
|
||
|
||
When you work with a large file, run check.rdb first. It will find the tab problems and give
|
||
you the information you need to find them. Then use a text editor to correct the problem.
|
||
|
||
You can move down to the first bad line by typing the following vi command :5. This takes
|
||
you to line 5. Then to see the line, type the list command I:. (This is the letter el, not the
|
||
number one). Or to do it in one step (move and list), type :51. Or you can using the
|
||
following colon command to set all of the lines in the file to display tabs:
|
||
|
||
rset list
|
||
To return it to normal display, use the command:
|
||
rset nolist
|
||
|
||
Edit in whatever changes you need, then go to the next bad line. You can change a space to
|
||
a tab with the following command:
|
||
|
||
ts/ /*I/
|
||
|
||
where the “I is the key on your keyboard that produces a tab. If you want to list three lines
|
||
above and below the bad line. type:
|
||
|
||
2-3,4+31
|
||
|
||
If you use ve to enter your data, you will have fewer problems like this. Data from foreign
|
||
sources should be checked carefully before you use it with /rdb.
|
||
|
||
See Also
|
||
see, ve
|
||
COHERENT Lexicon: elvis, me, vi
|
||
|
||
Notes
|
||
|
||
This command is named check.rdb rather than check, as in other implementations of
|
||
/rdb, to avoid clashing with the COHERENT command check, which does something very
|
||
different.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 196 / Buchseite 186 ====
|
||
186 chr —clear.rdb
|
||
|
||
chr — /rdb Command
|
||
Display the character corresponding to a number
|
||
chr number ...
|
||
|
||
chr converts each of the integers on its command line to its corresponding ASCII character.
|
||
You can use it to send special characters to the screen. This gives you a good way to
|
||
produce special characters that are hard to type or are interpreted by the shell.
|
||
|
||
Example
|
||
Here we convert several characters.
|
||
|
||
chr 97 65 49
|
||
aAl
|
||
|
||
chr 7
|
||
[beep]
|
||
|
||
echo ‘chr 7‘Wake up
|
||
[beep]Wake up
|
||
|
||
The [beep] is the sound. It does not print on your terminal.
|
||
|
||
See Also
|
||
|
||
ascii
|
||
COHERENT Lexicon: ASCII
|
||
|
||
Clear.rdb — /rdb Command
|
||
Clear the terminal's screen
|
||
clear.rdb
|
||
|
||
The command clear.rdb clears your terminal screen of all characters and leaves the cursor
|
||
in the upper left corner. It is useful for menus and forms that look better on a clear screen.
|
||
|
||
clear.rdb uses the termcap file of terminal capabilities to find the string of special
|
||
characters that are needed to clear your screen. To work correctly, the TERM
|
||
environmental variable must be set correctly to the name of your terminal as listed in
|
||
/etc/termcap.
|
||
|
||
The COHERENT command clear.rdb also clears the screen.
|
||
|
||
The /rdb command termput can also clear the screen, as follows:
|
||
termput cl
|
||
|
||
Speed
|
||
|
||
clear.rdb is quite fast, but there is a much faster way. Set a shell variable CLEAR to the
|
||
output of the command clear.rdb like this:
|
||
|
||
export CLEAR=‘clear’
|
||
Then you can use:
|
||
echo “$CLEAR"
|
||
|
||
in your shell programs for a fast clear. Put it into your .profile so that it will always be
|
||
available. Use quotation marks around the shell variables in case they have special
|
||
characters in them.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 197 / Buchseite 187 ====
|
||
close —column 187
|
||
|
||
See Also
|
||
|
||
termput
|
||
|
||
COHERENT Lexicon: clear, export, .profile, sh, TERM, termcap
|
||
|
||
Notes
|
||
|
||
This command is named clear.rdb rather than clear, as in other implementations of /rdb,
|
||
to avoid clashing with the COHERENT command clear.
|
||
|
||
close — /act/gl Command
|
||
|
||
Close accounting period creating journal for next
|
||
|
||
close
|
||
|
||
The command close is part of the accounting/general-ledger system that is included with
|
||
/rdb. It closes an accounting period, such as a month, quarter, or year, and creates the
|
||
next period's journal, the table journalnext. When you start the next period, carry the
|
||
journalnext forward by mving it to file journallast.
|
||
|
||
Example
|
||
|
||
The command close creates a file whose output resembles the following:
|
||
Credit Ref
|
||
|
||
Account Date
|
||
|
||
1010 850101
|
||
1110 850101
|
||
1310 850101
|
||
1330 850101
|
||
1420 850101
|
||
4997 850101
|
||
|
||
column — /rdb Command
|
||
|
||
display columns of a table in any order
|
||
|
||
Debit
|
||
11178
|
||
22130
|
||
0
|
||
0
|
||
0
|
||
|
||
33308
|
||
|
||
column [ Column... ] < tableorlist
|
||
|
||
jl
|
||
|
||
Description
|
||
|
||
brought
|
||
brought
|
||
brought
|
||
brought
|
||
brought
|
||
brought
|
||
|
||
forward
|
||
forward
|
||
forward
|
||
forward
|
||
forward
|
||
forward
|
||
|
||
The command column reads tableorlist and writes a new table (or list) that consists of each
|
||
Column, in the order you list them on the command line.
|
||
|
||
If you give a column name that is not one of the columns for tableorlist, column creates a
|
||
new column with that name, in that location, and leaves it empty. This lets you to create
|
||
new columns. If you want to compute a column that does not exist, use this column
|
||
facility to create it, then use the compute command to compute it. However, if you misspell
|
||
|
||
a column name, you will get an empty column.
|
||
|
||
If you name no Column on the command line. column writes all of tableorlist to the
|
||
standard output without change.
|
||
|
||
Example
|
||
|
||
Assume that you have an inventory table. as follows:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 198 / Buchseite 188 ====
|
||
188
|
||
|
||
column
|
||
|
||
Item Amount Cost Value
|
||
|
||
1 3 5.00 0
|
||
2 100 0.50 0
|
||
3 5 8.00 0
|
||
4 23 1.98 0
|
||
5 99 2.45 0
|
||
6 89 14.75 0
|
||
7 5 175 f°)
|
||
|
||
The command:
|
||
|
||
Description
|
||
rubber gloves
|
||
test tubes
|
||
clamps
|
||
|
||
plates
|
||
cleaning cloth
|
||
bunsen burners
|
||
scales
|
||
|
||
column Cost Amount Description < inventory
|
||
|
||
produces the following output:
|
||
Cost Amount Description
|
||
|
||
5.00 3 rubber gloves
|
||
|
||
0.50 100 test tubes
|
||
|
||
8.00 5 clamps
|
||
|
||
1.98 23 plates
|
||
|
||
2.45 99 cleaning cloth
|
||
|
||
14.75 89 bunsen burners
|
||
175 5 scales
|
||
|
||
Note that the columns Cost and Amount have been reversed. We only have the columns
|
||
we asked for and in the order we requested.
|
||
|
||
column can also manipulate list-formatted files. For example, the mailing list called maillist
|
||
|
||
looks like this:
|
||
Number 1
|
||
Name Ronald McDonald
|
||
|
||
Company McDonald’‘s
|
||
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
|
||
|
||
If you want only the names and numbers. type:
|
||
|
||
column Name Phone < maillist
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 199 / Buchseite 189 ====
|
||
commands — compresss_ 189
|
||
|
||
This produces the following output:
|
||
|
||
Name Ronald McDonald
|
||
Phone (111) 222-3333
|
||
|
||
Name Chiquita Banana
|
||
Phone 1234
|
||
|
||
See Also
|
||
|
||
project, row
|
||
COHERENT Lexicon: awk
|
||
|
||
commands — /rdb Command
|
||
Describe /rdb commands
|
||
commands
|
||
|
||
The command commands displays a table of /rdb commands, with a one-line description
|
||
and the syntax of each command.
|
||
|
||
See Also
|
||
|
||
act, helpme, rdb, whatis, whatwill
|
||
|
||
compresss — /rdb Command
|
||
Squeeze out all leading and trailing blanks
|
||
compresss [-b] < tableorlist
|
||
|
||
The command compresss removes all leading and trailing blanks from every column or field
|
||
in tableorlist. You an use it to save disk space.
|
||
|
||
Please note that the name compresss is not a typographical error. The command is spelled
|
||
in this way to avoid collision with the COHERENT command compress, which behaves very
|
||
differently from compresss.
|
||
|
||
compresss is almost the opposite of the command justify. Your files are not as pretty when
|
||
compressed as they are when justified, but they are smaller — usually one third the size or
|
||
less. Therefore, they take less disk space and are much faster to process; after all, most of
|
||
the time used to execute data-base programs consists of moving data from the disk to the
|
||
memory and, sometimes, back to the disk.
|
||
|
||
Multiple blanks that separate words are left alone.
|
||
Options
|
||
|
||
compresss recognizes the following option:
|
||
-b Drop blank lines. Don’t use this option with list files!
|
||
|
||
Example
|
||
For example, consider table oldjournal, which is as follows:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 200 / Buchseite 190 ====
|
||
190 compute
|
||
Date Account Debit Credit Description
|
||
890102 101 25000 cash from loan
|
||
890102 211.1 25000 loan number #378-14 Bank Amerigold
|
||
890103 150.1 10000 test equipment from Zarkoff
|
||
890103 101 5000 cash payment
|
||
890103 212.62 5000 note payable to Zarkoff Equipment
|
||
890104 130 30000 inventory - parts from CCPSC
|
||
890104 201.1 15000 accounts payable to CCPSC
|
||
890104 101 15000 cash payment to CCPSC for parts
|
||
|
||
After we run the command
|
||
compresss <old.journal | see
|
||
|
||
old.journal has no extra spaces. We prove this by piping the output to the /rdb command
|
||
see, which displays the following output:
|
||
|
||
Date*IAccount *IDebit *ICredit *IDescription$
|
||
|
||
890102*I101*I25000*I*Icash from loan$
|
||
890102*I211.1*I*I25000*Iloan number #378-14 Bank Amerigold$
|
||
890103*I150.1*1I10000*I*Itest equipment from Zarkoff$
|
||
890103*1I101*I*I5000*Icash payment$
|
||
890103*1I211.2*I*I5000*Inote payable to Zarkoff Equipment$
|
||
890104*I130°I30000*I*Iinventory - parts from CCPSc$
|
||
890104°I201.1*I*I15000*Iaccounts payable to CCPSc$
|
||
890104*I101*I*I15000*Icash payment to CCPSC for parts$
|
||
|
||
Note that see turns all of the tabs into “I and puts a dollar sign ‘S' at the end of each row to
|
||
show us that there are no spaces at the end.
|
||
|
||
See Also
|
||
|
||
justify, rmblank
|
||
|
||
Notes
|
||
|
||
Do not confuse this command with the COHERENT system's command compress, which
|
||
produces binary output that cannot be read by any /rdb command.
|
||
|
||
compute — /rdb Command
|
||
|
||
Calculate columns of a table
|
||
compute 'column = expression [ ; ... ]’ < tableorlist
|
||
|
||
The command compute lets you to do arithmetic on columns. A column can be computed
|
||
as a function of other columns, of itself, and of constants.
|
||
|
||
compute uses the COHERENT command awk to perform its work, as does the command
|
||
row. awk is a a powerful, interpreted programming language in which you can write
|
||
programs to perform complex transformations on text. The advantage of compute, over
|
||
awk is that compute knows about the names of columns in a table; this permits you to use
|
||
column names instead of column positional numbers. (In awk the second column is named
|
||
$2.) To grasp the full power of compute and row, read the COHERENT system's awk
|
||
tutorial. If you must perform very complex manipulations of tables. use awk.
|
||
|
||
If you must create a new empty column for compute to put values into. use the command
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 201 / Buchseite 191 ====
|
||
compute 191
|
||
|
||
column. This command creates an empty column for any column it cannot find in the
|
||
header line.
|
||
|
||
Example
|
||
|
||
This example computes a column from other columns:
|
||
compute ‘Value = sprintf("%5.2f", Cost * Amount)’ < inventory
|
||
|
||
Item Amount Cost Value Descriptioi
|
||
|
||
SI 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
|
||
|
||
Here are more examples of what you can do with compute. You can change the format of
|
||
column by using a C-style sprintf:
|
||
|
||
compute ‘column = sprintf ("%8.2f", column)’ < tableorlist
|
||
You can set column equal to the length of the string in column2:
|
||
|
||
compute ‘column = length (column2)’ < tableorlist
|
||
You can also Set column equal to the natural logarithm of column2:
|
||
|
||
compute ‘column = sprintf("%f", log (column2))’ < tableorlist
|
||
Or, you can increment column2 whenever column is greater than number:
|
||
|
||
compute ‘if (column > number) column2 = \
|
||
sprintf("%d", column2+1)’ < tableorlist
|
||
|
||
Expressions
|
||
|
||
As you can see, you can write rather complex expressions for compute. By expression, we
|
||
mean many kinds of equations. For example, a variable or a column is an expression. So is
|
||
variable + variable. So are rather complex equations. The following symbols indicate some
|
||
of the more complex expressions:
|
||
|
||
column
|
||
Name of a column, exactly as it appears at the top of the column.
|
||
|
||
= Make the column on the left equal the expression on the right.
|
||
|
||
+ Add
|
||
|
||
- Subtract
|
||
|
||
Multiply
|
||
|
||
/ ‘Divide.
|
||
|
||
% Modulo (zero if left value is equally divisible by right).
|
||
|
||
Statement separator needed if more than one equation
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 202 / Buchseite 192 ====
|
||
192
|
||
|
||
compute
|
||
|
||
log()
|
||
Natural logarithm of value or column within parentheses.
|
||
|
||
length0
|
||
String length of string in column.
|
||
|
||
You can also use C language-like statements:
|
||
|
||
if (expression) equation [ else equation };
|
||
For example:
|
||
|
||
if (Value > 10000) Status = "Special"; else Status = "Normal";
|
||
while (expression) equation;
|
||
|
||
For example:
|
||
|
||
while (column => 0) column -= 1 ;
|
||
|
||
for (expression; condition; expression) equation;
|
||
For example:
|
||
|
||
for (i = 0; i < columnl; i++) array [i] = column2 + i ;
|
||
You can also use the awk format pattern { action}. For example:
|
||
compute ‘length > 80 { print NR, "Line too long." }‘ < table
|
||
|
||
awk recognizes length as a function that returns the length of the row and NR as the line
|
||
number, Note that the line numbers of a file starts with the head line, while row numbers
|
||
of a table starts after the dash line (line 3).
|
||
|
||
What Is a Column Name?
|
||
|
||
compute looks up, in the column header of the input file. each word that it finds in its
|
||
command-line program. If there is a match, compute converts the column name to its
|
||
position (first, second, third, etc.) depending upon the relative location of the column.
|
||
These column numbers are needed by awk.
|
||
|
||
compute defines a column name to be a string of the following characters:
|
||
1. Upper and lower letters, numbers, and the underscore *_’.
|
||
2. Any string that is enclosed by apostrophes or quotation marks.
|
||
|
||
Therefore, if you want special characters in your column names, put quotation marks
|
||
around them when you use them. For example:
|
||
|
||
compute ’ “Item#" = NR ’ < inventory
|
||
|
||
Note the quotation marks around the column head Item# because of the number character
|
||
‘#’, Also, note that we used quotation marks, because the whole program was enclosed in
|
||
apostrophes. If you use one kind of mark around the whole program, use the other kind of
|
||
mark around the column names that have special characters in them.
|
||
|
||
Reserved Words to Avoid in Column Names
|
||
|
||
Some words are understood by awk. Therefore, they should not be used in column names.
|
||
A simple way to avoid a conflict is to start your column names with a capital letter. awk
|
||
does not confuse Print with print. Here is a list of awk’s built-in functions.
|
||
|
||
Reserved Words Description
|
||
|
||
BEGIN.. Patternthat matches before first input record
|
||
Patternthat matches after last input record
|
||
...Getout of for or while loop
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 203 / Buchseite 193 ====
|
||
compute 193
|
||
|
||
..Goto next iteration of for or while loop
|
||
|
||
Usedin "if then else" expression
|
||
|
||
Leaveprogram entirely as if end of input
|
||
Raisenumber to a power
|
||
|
||
for{ expression ; condition ; expression ) statement
|
||
.Getnext input line
|
||
|
||
if{ condition ) statement [ else statement ]
|
||
|
||
for{ variable in array ) statement
|
||
|
||
index( string], string2 )
|
||
|
||
Truncateargument to integer
|
||
|
||
Returncurrent line length, or length of argument
|
||
Returnlog (to base 2) of argument
|
||
|
||
Skipto next record and reexecute all commands
|
||
Outputvariables
|
||
|
||
printf{"format", variable, ... )
|
||
|
||
split( string. arrayname, separator)
|
||
sprintf("format", variable, ... )
|
||
|
||
Returnsquare root of argument
|
||
|
||
substr( string, start. number )
|
||
|
||
-while( condition ) statement
|
||
|
||
Programs
|
||
Often you want to use a shell variable in a compute command. It is easy, if you
|
||
understand what is going on. For example, the following commands:
|
||
|
||
DATE=860101
|
||
compute "Date = $DATE" < journal
|
||
produce the following output:
|
||
|
||
Date Account Debit Credit Description
|
||
|
||
860101 101 25000 cash from loan
|
||
|
||
860101 211.1 25000 loan number #378-14 Bank Amerigold
|
||
860101 150.1 10000 test equipment from Zarkoff
|
||
860101 101 5000 cash payment
|
||
|
||
860101 211.2 5000 note payable to Zarkoff Equipment
|
||
860101 130 30000 inventory - parts from CCPSC
|
||
860101 201.1 15000 accounts payable to CCPSC
|
||
|
||
860101 101 15000 cash payment to CCPSC for parts
|
||
|
||
We set a shell variable named DATE to a date. Then we used the variable in the compute
|
||
command line program. But note that we had to use quotation marks (") instead of our
|
||
usual apostrophes (’). To the shell, apostrophes protect absolutely. With apostrophes, the
|
||
shell would not see the dollar sign ‘S’ in front of DATE and would not convert it to its value.
|
||
The quotation mark protects the enclosed from the shell, also, except for shell variables and
|
||
command substitution (‘cmd'). With quotation marks, the shell will still replace variables
|
||
(which start with a dollar sign character).
|
||
|
||
There is one further complication. The previous worked fine because the value of date was
|
||
a number. But if we want to use strings in awk, they must have quotation marks (not
|
||
apostrophes) around them. For example:
|
||
|
||
COMPANY='Makeapile, Inc.’
|
||
compute “Company = \"$COMPANY\"" < maillist
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 204 / Buchseite 194 ====
|
||
194 compute
|
||
|
||
produces the following:
|
||
|
||
Number 1
|
||
|
||
Name Ronald McDonald
|
||
Company Makeapile, Inc.
|
||
Street 123 Mac Attack
|
||
City Memphis
|
||
|
||
State TENN
|
||
|
||
ZIP 30000
|
||
|
||
Phone (111) 222-3333
|
||
Number 2
|
||
|
||
Name Chikeeta Banana
|
||
Company Makeapile, Inc.
|
||
Street Uno Avenito De La Revolution
|
||
City San Jose
|
||
|
||
State El Salvadore
|
||
ZIP 123456789
|
||
Phone 1234
|
||
|
||
Here we set a shell variable COMPANY to a company name. We want to update the mail list
|
||
because these characters have been hired by a new company. Note what we had to do. We
|
||
needed quotation marks around the whole program to let the shell substitute the value of
|
||
the shell variable. But we also needed quotation marks around the string “Makeapile, Inc.”
|
||
for awk. So we have to protect the innermost quotation marks with backslashes.
|
||
|
||
There is another way. which opens up a little window in the program for the shell to insert
|
||
strings. But it fails when there are spaces in the window string. So use the method
|
||
previously discussed.
|
||
|
||
Problem With awk Floating-Point Format
|
||
|
||
With some implementations of awk, the value column is computed to much greater
|
||
precision than you are likely to want. For example, version produces this table:
|
||
|
||
Item# Amount Cost Value Description
|
||
|
||
1 3 5.00 15 rubber gloves
|
||
|
||
2 100 0.50 50 test tubes
|
||
|
||
| 5 8.00 40 clamps
|
||
|
||
4 23 1.98 45.539997100830078125 plates
|
||
|
||
5 99 2.45 242.5499725341796875 cleaning cloth
|
||
6 89 14.75 1312.75 bunsen burners
|
||
|
||
7 5 175.00 875 scales
|
||
|
||
To control the precision of the floating-point values in a column, you can use the sprintf
|
||
function from the C programming language that has been implemented in awk. For
|
||
example:
|
||
|
||
compute ‘Value = sprintf ("%7.2f", ( Cost * Amount ))' < inventory
|
||
These commands will produce the first table under Examples, above.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 205 / Buchseite 195 ====
|
||
computedate — consolidate 195
|
||
|
||
See Also
|
||
COHERENT Lexicon: awk, ksh, sh
|
||
|
||
computedate — /rdb Command
|
||
|
||
Add given number of days to a date
|
||
computedate date days
|
||
|
||
The command computedate adds days to a date, and displays the new date. date must be
|
||
the format YYMMDD; days can be negative or positive. computedate displays the new date
|
||
in the same format. This is the best format for entering dates in a column because they sort
|
||
correctly and take only six characters.
|
||
|
||
Internally, computedate converts the date to julian, adds days, then converts the date back
|
||
to gregorian. Suppose we want to know the date 45 days from March 31, 1989. We can
|
||
type
|
||
|
||
computedate 890331 45
|
||
|
||
This command returns the string:
|
||
890515
|
||
|
||
That is May 15. 1989.
|
||
|
||
Another trick is to combine the todaysdate and the computedate programs. todaysdate
|
||
gives the date of today in the preferred format of YYMMDD. For example, the following
|
||
command shows us the date 45 days from today:
|
||
|
||
computedate ‘todaysdate’ 45
|
||
|
||
Data Validation
|
||
|
||
You can use computedate to validate a date. If you add zero days to a date and get a
|
||
different date, then the original date was not valid. For example, let's test the 32nd day of
|
||
January 1989:
|
||
|
||
computedate 890132 0
|
||
|
||
This returns the string 890201 or February 1, 1989. As we expected, we received a
|
||
different date. We can test this with the following shell program:
|
||
|
||
if test $DATE = ‘computedate $DATE 0’
|
||
then
|
||
echo OK
|
||
else
|
||
echo Invalid DATE
|
||
fi
|
||
|
||
See Also
|
||
gregorian, julian, todaysdate
|
||
|
||
consolidate — /act/g] Command
|
||
Combine all subsidiary journals to general journal
|
||
consolidate nextdate
|
||
|
||
The command consolidate is part of the accounting/general-ledger system that is included
|
||
with /rdb. It assembles all of the subsidiary journals, such as journalincome,
|
||
journalexpense, and journaldeposit, into the general journal named journal. It also
|
||
converts from single-entry to double-entry bookkeeping by totaling Debits and Credits and
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 206 / Buchseite 196 ====
|
||
196
|
||
|
||
cpdir.rdb
|
||
|
||
inserting counterbalancing adjustments to the cash account. It needs the nextdate for
|
||
these accounts.
|
||
|
||
Example
|
||
|
||
The command
|
||
consolidate $NEXTDATE
|
||
writes into file journal data that resemble the following:
|
||
|
||
Date Account Debit Credit Ref Description
|
||
|
||
890101 4370 2 Fe parking at clients
|
||
890103 4380 15 e115 shuttle bus to airport
|
||
890104 4380 a3 v meal
|
||
|
||
890105 4380 13 c116 meal
|
||
|
||
890106 4384 114 r hotel
|
||
|
||
890118 3100 3286 c101 consulting
|
||
|
||
890125 3080 250 c1459 book fees
|
||
|
||
891231 1010 5858 double-entry
|
||
|
||
891231 1010 17036 double-entry
|
||
|
||
891231 3010 13500 deposit from sales/deposit
|
||
891231 4020 3601 check from pur/check
|
||
891231 4030 2100 payroll from pay/journalpay
|
||
|
||
Note the double-entry adjustments, and the totals of journals from sales, purchasing, and
|
||
pay departments. The Date came from the NEXTDATE shell variable. which you must set
|
||
in your .profile.
|
||
|
||
See Also
|
||
|
||
getjournal
|
||
|
||
cpdir.rdb — /rdb Command
|
||
|
||
Copy one directory tree to another directory
|
||
cpdir.rdb fromdirectory todirectory
|
||
|
||
The command cpdir.rdb copies a directory tree — that is, all directories and their files —
|
||
from fromdirectory to todirectory.
|
||
|
||
cpdir.rdb uses the tar command in a special way. It is a shell program so you can read it
|
||
and see how it does it. It performs almost exactly the same work as the COHERENT
|
||
command cpdir.
|
||
|
||
Example
|
||
You might use this to back up a large directory:
|
||
|
||
cpdir.rdb /usr/rdb /usr/rdb. backup
|
||
The following moves a directory to a preferred place:
|
||
cpdir.rdb /usr/he,left/goodstuff /usr/project/goodstuff
|
||
|
||
See Also
|
||
COHERENT Lexicon: cpdir, tar
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 207 / Buchseite 197 ====
|
||
cstate— cursor 197
|
||
|
||
Notes
|
||
This command is named cpdir.rdb rather than cpdir, as in other implementations of /rdb,
|
||
to avoid clashing with the COHERENT command cpdir.
|
||
|
||
cstate — /act/sales
|
||
Produce customer statement
|
||
cstate
|
||
|
||
The command estate is part of the accounting/sales system that is included with /rdb. It
|
||
generates the customer statement from the tables salesorder and deposit. It shows what
|
||
the customer has ordered and paid, and the net. The result is printed as a form to be sent
|
||
to the customer as a bill.
|
||
Example
|
||
The following gives an example of the output of cstate:
|
||
Please enter customer number (or all or Return to exit): 3
|
||
|
||
Customer Statement
|
||
|
||
Makeapile, Inc., 123 Bigbucks Blvd., Dallas, TX 12345, 1-800-SOF-WARE
|
||
Mailing Address for Customer Number 3
|
||
Ms Ute Unix Ph.D. President
|
||
|
||
UniUniUniUni Software Sellers
|
||
12345 Nixuni Street
|
||
Union, New Jersey 11111 USA
|
||
|
||
Now Due and Payable is your balance of: 107550.00
|
||
|
||
Details of Your Orders and Payments
|
||
|
||
Cust Date Amount Ref
|
||
3 850902 -6300.00 17
|
||
3 850902 -14175.00 16
|
||
3 850902 -22050.00 4S:
|
||
3 850902 -23625.00 12
|
||
3 850902 -37800.00 13
|
||
3 850903 -12600.00 23
|
||
3 860105 9000.00 3347
|
||
|
||
-107550.00
|
||
|
||
Please enter customer number (or all or Return to exit):
|
||
|
||
See Also
|
||
|
||
act, vstate
|
||
|
||
cursor — /rdb Command
|
||
Move the cursor to the row and column requested
|
||
cursor row col [ CURSOR }
|
||
|
||
The command cursor move the cursor to screen position row and column. You can cursor
|
||
and the /rdb command clear.rdb to perform complex screen handling from within a shell
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 208 / Buchseite 198 ====
|
||
198 cursor
|
||
|
||
script. You can paint your screen with cursor moves and echo commands; then use the
|
||
read command to read the user's input; and finally use various COHERENT and /rdb
|
||
commands to examine and confirm the input. You can also clear fields of the screen by
|
||
moving the cursor and writing blanks.
|
||
|
||
You must give the row and column you want. cursor also needs the cursor movement (cm)
|
||
entry from file /etc/termcap. This can be given as an argument, but the easiest way is to
|
||
set up the shell variable called CURSOR then cursor will find it in its environment
|
||
automatically. To set up the CURSOR variable, do the following:
|
||
|
||
CURSOR=‘termput cm’
|
||
|
||
Another way is to use your text editor to find the entry in /etc/termcap and copy its cm
|
||
entry for your terminal to your .profile:
|
||
|
||
CURSOR=“[ [ $p1d; 8p28dH
|
||
|
||
This is the entry for the pe terminal. The uparrow bracket (“[) is the ESC character (<ctrl-
|
||
[>). The function tgoto function from the termcap library converts it into the proper escape
|
||
string.
|
||
|
||
Example
|
||
The following moves the cursor to the middle of an 80-by-24 screen:
|
||
|
||
cursor 11 38
|
||
Speed
|
||
|
||
cursor is fast, but there is a much faster way. Set a shell variable like L22 to move to the
|
||
22nd line:
|
||
|
||
L22=‘cursor 23 0’
|
||
Then you can use:
|
||
echo “$L22$MESSAGE\c"
|
||
|
||
in your shell programs for a fast cursor movement and to print a message. Note the
|
||
quotation marks around the messages in case there are special characters. Also note the
|
||
\¢e, which tells echo not to print a carriage return.
|
||
|
||
An even better trick is to use the shell feature that tests to see if a variable has been set and
|
||
only gives it a value when it needs one:
|
||
|
||
echo "${L22:=‘cursor 22 0‘}$MESSAGE\c"
|
||
|
||
All of this magic causes the shell to check if L22 has a value. If not, it executes the cursor
|
||
command and assigns the value to L22. Then, if this line is called in a loop, the next time
|
||
the value will have been set and will be about 20 times faster.
|
||
|
||
See Also
|
||
|
||
termput
|
||
COHERENT Lexicon: .profile, termcap
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 209 / Buchseite 199 ====
|
||
dash line — datatype 199
|
||
|
||
D
|
||
|
||
dash line — /rdb Definition
|
||
The dash line is the second line in an /rdb table. It underscores each entry in the table's
|
||
head line. Each entry in the dash line must be separated by a tab character.
|
||
Example
|
||
The table inventory appears as follows:
|
||
|
||
Item Amount Cost Value Description New
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
3 5 80 400 clamps
|
||
4 23 19 437 plates
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
The dash line is:
|
||
|
||
Note that there is one entry in the dash line for each entry in the head line.
|
||
|
||
See Also
|
||
head line, listtotable, tabletolist
|
||
|
||
datatype — /rdb Command
|
||
Display the data type of each column selected
|
||
datatype [-1] [column...] < table
|
||
|
||
The command datatype displays the type of data contained in each column. If you do not
|
||
name a column on the command line, datatype calculates and displays all of table's
|
||
columns.
|
||
|
||
Options
|
||
The -1 option tells datatype to print the entire contents of table, in addition to information
|
||
about each column.
|
||
|
||
Code
|
||
|
||
-1 Character strings with nonnumeric data.
|
||
|
||
0 Integer number.
|
||
|
||
1,2... Floating-point number (number of digits to the right of the decimal).
|
||
|
||
Example
|
||
The following shows a sample output of datatype:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 210 / Buchseite 200 ====
|
||
200 dBASE crossreference
|
||
|
||
Int Char Float2 Float4
|
||
1 a 1.2 1.1234
|
||
745 ZZ2Zz 8.54 12.3
|
||
|
||
to) -1 2 4
|
||
|
||
Note that the Int column has only integers in it (code 0), the Char column has characters in
|
||
it (code -1), and the two Float columns have different precisions (positive numbers codes).
|
||
Note that the float precision is the maximum.
|
||
|
||
See Also
|
||
ascii, chr, dbdict
|
||
|
||
dBASE crossreference — Technical Information
|
||
dBASE was developed and marketed by Ashton-Tate; this company was purchased recently
|
||
by Borland International.
|
||
|
||
The following table gives the /rdb and COHERENT equivalents for most common dBASE
|
||
commands. The slug in bold characters gives the dBASE command; the following
|
||
description gives the equivalent in /rdb and COHERENT commands:
|
||
|
||
ACCEPT Comment TO Variable
|
||
echo Comment ; read Variable
|
||
|
||
APPEND BLANK
|
||
echo >> Fileout
|
||
|
||
APPEND FROM Filename FOR Condition
|
||
row ‘Condition’ < Filename >> Fileout
|
||
|
||
BROWSE
|
||
more, scat, update, or any text editor
|
||
|
||
CANCEL
|
||
DEL (any character set with stty)
|
||
|
||
CHANGE Range FIELD Fieldname FOR Condition
|
||
compute ‘Range && Condition {Fieldname = Value}' < Filein
|
||
|
||
CLEAR
|
||
CLEAR GETS
|
||
clear
|
||
|
||
CONTINUE
|
||
continue [shell statement]
|
||
|
||
COPY TO Filename FIELD Fieldnames FOR Condition
|
||
row ‘Condition’ < Filein | column Fieldnames > Filename
|
||
|
||
COUNT FOR Condition TO Variable FOR Condition
|
||
row ‘Condition’ < Filein | tail +3 | we -1
|
||
|
||
CREATE Filename
|
||
> Filename ; vi Filename ; ve Filename ; cmd > Filename
|
||
|
||
DELETE RECORD Number
|
||
(sed SNUM+1}q Filename ; tail +S NUM+3}) > tmp; mv tmp Fieldname
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 211 / Buchseite 201 ====
|
||
dBASE crossreference 201
|
||
|
||
DELETE NEXT Number
|
||
DELETE ALL
|
||
sed 2q Filename > tmp ; mv tmp Filename
|
||
|
||
DELETE NEXT Number FOR Condition
|
||
DELETE FILE Fieldname
|
||
> Filename
|
||
|
||
DISPLAY Range FOR Bedingung Field OFF
|
||
row ‘Range && Dedingung’ < Filename | column Fieldnames
|
||
|
||
DISPLAY STRUCTURE
|
||
for I in * do sed 2q; done
|
||
|
||
DISPLAY MEMORY
|
||
df; du
|
||
|
||
DISPLAY FILES ON Disk LIKE Datatype
|
||
Is *Datatype ; ls Disk/*Datatype
|
||
|
||
) Program
|
||
Program
|
||
|
||
CASE Condition
|
||
Condition) [shell case statement]
|
||
|
||
OTHERWISE
|
||
*) [shell case statement]
|
||
|
||
DO WHILE Condition CR ENDDO
|
||
while Condition CR do done
|
||
|
||
EDIT
|
||
vi, ve, update, ex, ed, me, other editors and commands
|
||
|
||
ECT
|
||
ENDDO
|
||
do [in shell while, until, for statements]
|
||
|
||
ERASE
|
||
clear
|
||
|
||
FIND Text
|
||
/Text (in vi, ve, update)
|
||
|
||
INDEX ON Fieldname TO Filename
|
||
index Filename Fieldname ...
|
||
|
||
USE Filename INDEX Keyfield
|
||
search Filename Keyfield
|
||
|
||
INPUT Text To Variable
|
||
Variable=Text
|
||
|
||
INSERT
|
||
sed ${NUM}q Filename; echo SRECORD; tail +$NUM Filename
|
||
|
||
JOIN TO Filename FOR Condition FIELDS Fieldnames
|
||
jointable Filename1 Filename2
|
||
row ‘Condition’ < Filename2 | jointable Filename] -
|
||
column Fieldnames < Filename2 | jointable Filename -
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 212 / Buchseite 202 ====
|
||
202
|
||
|
||
dBASE crossreference
|
||
|
||
Column,Row SAY Comment GET Variable PICTURE
|
||
tput Column ; tput Row ; echo Comment ; READ Variable
|
||
|
||
GO
|
||
|
||
GOTO
|
||
|
||
GO RECORD n
|
||
ve nG
|
||
|
||
GO Fieldname
|
||
ve /
|
||
|
||
GO TOP
|
||
ve H
|
||
|
||
GO BOTTOM
|
||
ve L
|
||
|
||
IF Condition Statement2 ELSE Statement2 ENDIF
|
||
if Condition then Statement] else Statement? fi
|
||
|
||
LOCATE FOR Condition
|
||
|
||
row ‘Condition’ < Filename
|
||
LOOP
|
||
|
||
while, until. for [shell statements]
|
||
MODIFY STRUCTURE
|
||
|
||
column New Fieldnames < Filename
|
||
NOTE
|
||
REMARK
|
||
|
||
: Old Comment
|
||
# New Comment
|
||
|
||
MOVE Old-Filename TO New-Filename
|
||
mv Old-Filename New-Filename
|
||
|
||
REPLACE Range Fieldname WITH Expression FOR Condition
|
||
compute ‘Fieldname = Expression’ < Filename
|
||
compute ‘Range && Condition {Fieldname = Expression}’ < Filename
|
||
|
||
REPORT Form FOR Condition TO PRINT
|
||
report Form < Filename
|
||
row ‘Condition’ < Filename | report Form | print
|
||
|
||
PACK
|
||
|
||
compress, uncompress [COHERENT]
|
||
QUIT
|
||
|
||
<ctrl-D>
|
||
|
||
READ
|
||
read Variable
|
||
|
||
RECALL Condition
|
||
row ‘Condition’ < Filename
|
||
|
||
RELEASE Variable
|
||
Variable=
|
||
|
||
RESET
|
||
RESTORE FROM Filename
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 213 / Buchseite 203 ====
|
||
dbdict 203
|
||
|
||
RETURN
|
||
return [shell]
|
||
|
||
SAVE TO Filename
|
||
SELECT
|
||
row, column, etc.
|
||
|
||
SET
|
||
set [shell]
|
||
SKIP
|
||
|
||
SORT ON Fieldname TO Filename
|
||
sorttable Fieldname > Filename
|
||
|
||
STORE Expression TO Variable
|
||
Variable="Expression’
|
||
|
||
SUM Fieldname TO Variable FOR Condition
|
||
Variable='row ‘Condition’ < Filename | column Fieldname*
|
||
|
||
TOTAL ON Keyfield TO Filename FIELDS Fieldnames FOR Condition
|
||
row ‘Condition’ | subtotal Keyfield Fieldnames > Filename
|
||
|
||
UPDATE FROM Filename ON Keyfield
|
||
update, vi, ve, replace, append, delete, etc.
|
||
|
||
USE Filename
|
||
cmd < Filename
|
||
|
||
WAIT
|
||
wait [shell]
|
||
|
||
@ Row,Column SAY expression
|
||
cursor Row Column; echo EXPRESSION
|
||
ve screen and validation file
|
||
|
||
All data-base systems have some method for importing text files. Sometimes you'll be able
|
||
to use the header information that comes with /rdb tables, and sometimes you'll have to
|
||
specify this information to the target system anyway.
|
||
|
||
dbdict — /rdb Command
|
||
|
||
Print a data-base dictionary
|
||
dbdict < table
|
||
|
||
The command dbdict prints a table of two columns: The first gives the names of each field
|
||
in table, and the second gives the field numbers.
|
||
|
||
Example
|
||
For example. we might have a table named journal that looks like this:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 214 / Buchseite 204 ====
|
||
204 = delete
|
||
|
||
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
|
||
|
||
The command
|
||
dbdict < journal
|
||
produces the following:
|
||
|
||
field name
|
||
1 Date
|
||
|
||
2 Account
|
||
|
||
3 Debit
|
||
|
||
4 Credit
|
||
|
||
5 Description
|
||
|
||
delete — /rdb Command
|
||
Blank record and update index file
|
||
delete [-m[bhirs]] table keycolumn ... < keytable
|
||
|
||
The command delete writes a blank record on the row in table whose key matches the row
|
||
in the keytable. It also deletes the offset row in the appropriate fast-access offset table. or, in
|
||
the case of the hash method, replaces the deleted offset with -1.
|
||
|
||
Options -m[bhirs] lets you select a type of fast-accessing to locate the row to delete. For
|
||
information on the type of fast accessing that each option invokes, see the manual entry for
|
||
index.
|
||
|
||
Example
|
||
Consider table inventory. which appears as follows:
|
||
|
||
Item Amount Cost Value Description
|
||
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
|
||
3 5 80 400 clamps
|
||
|
||
4 23 19 437 plates
|
||
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
The record index looks like this:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 215 / Buchseite 205 ====
|
||
difference 205
|
||
|
||
Offset
|
||
76
|
||
|
||
113
|
||
147
|
||
177
|
||
207
|
||
245
|
||
283
|
||
|
||
The following command deletes the first record Item1:
|
||
echo 1 | delete -mr inventory Item
|
||
|
||
inventory now appears as follows:
|
||
|
||
Item Amount Cost Value Description
|
||
2 100 5 500 test tubes
|
||
3 5 80 400 clamps
|
||
4 23 19 437 plates
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 3 175 875 scales
|
||
|
||
inventory.r now appears as follows:
|
||
Offset
|
||
|
||
113
|
||
147
|
||
197
|
||
207
|
||
245
|
||
283
|
||
|
||
Note that we have blanked out the record and removed the offset.
|
||
|
||
See Also
|
||
append, index, replace
|
||
|
||
difference — /rdb Command
|
||
Output table of rows that are in only one table
|
||
difference table1 table2
|
||
|
||
The command difference uses the COHERENT commands sort and uniq to subtract
|
||
logically table2 from table1. Its output consists of the rows that are in table] but not in
|
||
table2. The two input tables must have the same columns (union compatible in the technical
|
||
data-base literature), and the rows must be exactly identical — including every space, tab,
|
||
and nonprinting character. If two rows look the same to you but not to difference, try the
|
||
see command to discover any blank spaces and nonprinting characters.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 216 / Buchseite 206 ====
|
||
206 = display
|
||
|
||
Example
|
||
|
||
In this example, consider the table journal, which appears as follows:
|
||
|
||
Date
|
||
|
||
Amount
|
||
|
||
Account Ref
|
||
|
||
Description
|
||
|
||
820107
|
||
820113
|
||
820114
|
||
820114
|
||
820119
|
||
820121
|
||
820121
|
||
820125
|
||
|
||
2500.00
|
||
99.00
|
||
|
||
keogh
|
||
dues
|
||
|
||
¢adcaaade
|
||
|
||
meal with jones
|
||
|
||
car repairs
|
||
|
||
car insurance allstate
|
||
|
||
car registration dmv
|
||
|
||
sundown vitamins
|
||
|
||
meal with scott
|
||
|
||
keogh payment
|
||
|
||
dues to uni-ops unix conference
|
||
|
||
And consider the table carexpense, which appears as follows:
|
||
|
||
Date
|
||
|
||
Amount Account Ref
|
||
|
||
Description
|
||
|
||
820113
|
||
820114
|
||
820114
|
||
|
||
101.62
|
||
81.80
|
||
93.00
|
||
|
||
The command
|
||
|
||
car
|
||
insur
|
||
car
|
||
|
||
car repairs
|
||
car insurance allstate
|
||
car registration dmv
|
||
|
||
difference journal carexpense
|
||
|
||
logically “subtracts” carexpense from journal, to produce the following output:
|
||
|
||
Date
|
||
|
||
Amount
|
||
|
||
Account Ref
|
||
|
||
Description
|
||
|
||
820107
|
||
820119
|
||
820121
|
||
820121
|
||
820125
|
||
|
||
See Also
|
||
|
||
14.00
|
||
81.72
|
||
20.83
|
||
2500.00
|
||
99.00
|
||
|
||
meal
|
||
vitamin
|
||
meal
|
||
keogh
|
||
dues
|
||
|
||
Vv
|
||
c
|
||
Vv
|
||
c
|
||
Vv
|
||
|
||
meal with jones
|
||
|
||
sundown vitamins
|
||
|
||
meal with scott
|
||
|
||
keogh payment
|
||
|
||
dues to uni-ops unix conference
|
||
|
||
COHERENT Lexicon: diff, diff3, sort, uniq
|
||
|
||
display — /rdb Command
|
||
Write table or list file to standard output
|
||
display < tableorlist
|
||
|
||
The command display copies tableorlist from the standard input to the standard output.
|
||
This is not a very useful program, but is a template for the C interface programs. If you
|
||
have its source code, you have an example of how to process tables and lists and can modify
|
||
it for your own programs.
|
||
|
||
display is slower than the COHERENT command cat because it does more processing.
|
||
display knows about table and list formats, and reads and writes one row at a time.
|
||
|
||
See Also
|
||
|
||
COHERENT Lexicon: cat, more
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 217 / Buchseite 207 ====
|
||
domain 207
|
||
|
||
domain — /rdb Command
|
||
|
||
Display invalid values in a column
|
||
domain domaintable [string ...] [< one-column-table]
|
||
|
||
The command domain displays all strings or all rows in one-column-table that do not match
|
||
any entry in the domaintable.
|
||
|
||
domain is useful for validating that each item in a column is legitimate. First. build a file
|
||
that consists of a list of all legal values. In relational theory, these values are called the
|
||
domain of the column. (You can also use the command validate to validate numbers and
|
||
short lists of valid strings.)
|
||
|
||
To check the domain of a column in a multicolumn table. simply use the command column
|
||
to project the column you want.
|
||
|
||
The domaintable must be sorted because it be searched by the command search using the
|
||
binary fast-access method (-mb). domain is a shell script, so you can edit it to change its
|
||
search method,
|
||
|
||
Example
|
||
|
||
You might have an order file for cars like this:
|
||
|
||
Qty Model Colors Options
|
||
1 sedan black 3
|
||
1 sedan green 1
|
||
1 sedan farble 4
|
||
3 sedan red 5
|
||
2 convert white 1
|
||
1 sedan purple 2
|
||
1 sedan yellow 4
|
||
3 convert blue 2
|
||
|
||
You would also need a sorted file of possible car colors:
|
||
|
||
silver
|
||
white
|
||
|
||
Now we can validate the Color column and see all unacceptable colors:
|
||
column Colors < orders | domain colors :
|
||
|
||
This produces the following output:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 218 / Buchseite 208 ====
|
||
208 domain
|
||
|
||
Colors
|
||
|
||
domain complains about farble and yellow because neither color is in our domain list.
|
||
|
||
You can invoke orders in the text editor and edit it, or add those colors to the approved list.
|
||
In vi use the /pattern command to find all of the patterns in the orders file. Another
|
||
approach is to type something like this:
|
||
|
||
1g/farble/s//purple/g
|
||
|
||
This vi command will find all instances of farble and change them to purple.
|
||
|
||
You can also validate strings written on the command line. For example, the command
|
||
domain colors red blue purple farble yellow green
|
||
|
||
also prints the output:
|
||
|
||
farble
|
||
yellow
|
||
|
||
These command-line stings should be quoted if they have any special characters in them.
|
||
They are sought by the command grep. If they contain a dollar sign ‘$', it should be
|
||
protected with three backslashes: this expression is scanned both by the shell and by grep,
|
||
and it takes three backslashes to get one backslash through to grep.
|
||
|
||
See Also
|
||
|
||
column, search, validate, ve
|
||
COHERENT Lexicon: egrep, grep, sort, uniq
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 219 / Buchseite 209 ====
|
||
enter 209
|
||
|
||
enter — /rdb Command
|
||
Add rows to a table or list file without an editor
|
||
enter [-limit] tableorlist
|
||
|
||
The command enter is a simple way to append one or more rows to the end of tableorlist. It
|
||
displays each column name and waits for you to type each item.
|
||
|
||
enter is a substitute for the form-editor ve. It is easier to use, but very limited.
|
||
|
||
Note that this is one of the few /rdb commands that does not use the less-than symbol ‘<’ to
|
||
input a table, but requires the name of a table to which it is to append data.
|
||
|
||
If you make an error in entering a record, you can return to the last line by typing a caret
|
||
‘**; enter then prompts you with the previous line. If you return two lines, keep typing
|
||
carets until you are prompted for the line you wish to reenter.
|
||
|
||
Options
|
||
The option -limit lets you limit the number of rows to be entered. For example, -1 prompts
|
||
for one row and then exits. Thus, it can be used in a shell script.
|
||
|
||
Rules
|
||
To set up and enter a file in list format instead of table format, there are several rules and
|
||
suggestions.
|
||
|
||
First. let's discuss terminology. A list is like a table that is turned sideways. For example, a
|
||
wide table looks like this:
|
||
|
||
Number Name Company Street City State ZIP
|
||
Phone
|
||
|
||
1 Ronald McDonald McDonald’s 123 Mac Attack
|
||
Memphis TENN 30000 (111) 222-3333
|
||
|
||
Note that the row is so long that it wrapped around to the next line. Also, the column
|
||
names and column data do not line up. Names, Companies, and Street Addresses are
|
||
usually too long to fit nicely into such a table. Therefore, we need a list format like this:
|
||
|
||
Number 1
|
||
|
||
Name Ronald McDonald
|
||
Company McDonald’s
|
||
Street 123 Mac Attack
|
||
city Memphis
|
||
|
||
State TENN
|
||
|
||
ZIP 30000
|
||
|
||
Phone (111) 222-3333
|
||
|
||
These two formats (table and list) are made interchangeable by using two programs:
|
||
listtotable and tabletolist. You can enter and keep a file in list format. When you want to
|
||
use several commands, you can convert it to table format and pipe it into the regular
|
||
commands for faster execution. For example, the command
|
||
|
||
listtotable < maillist | column Name Phone | justify
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 220 / Buchseite 210 ====
|
||
210 _~— enter
|
||
|
||
produces the following output:
|
||
|
||
Name
|
||
|
||
Phone
|
||
|
||
Ronald McDonald (111) 222-3333
|
||
|
||
It is best, therefore, to remember that Name and Phone are column names. The
|
||
information that follows them in the list is the first row of a table (that can be created by the
|
||
|
||
command listtotable).
|
||
|
||
1. First use an editor to create the list file. Type each column name followed by one,
|
||
and only one, tab. Also enter the information for the first row (record).
|
||
|
||
2. Be sure to put a newline (blank line) as the first line of the file.
|
||
|
||
3. Be sure to put a blank line at the end of each row (record). In the previous
|
||
example, it should appear after the row Phone. This tells the program that it has
|
||
reached the end of the row.
|
||
|
||
You can then save the file and use the enter program. Type:
|
||
|
||
enter maillist
|
||
|
||
Name _
|
||
|
||
enter responds with the first column name and a tab, and waits for you to enter
|
||
whatever you wish for Name. The underscore ‘_’ shows where the cursor of your
|
||
terminal will be waiting for you to input data.
|
||
|
||
4. Type in your data for the item. Use the return key to end the information for this
|
||
item. If you type more than 80 characters or so, your terminal will wrap around.
|
||
You can continue to type and wrap around until you reach your editor's line limit or
|
||
press <Return>. Then enter gives you the name of the next column head. a tab,
|
||
and waits for your entry.
|
||
|
||
5. When enter has given you the first column name of a new record and is waiting for
|
||
a response, exit from it by typing <ctrl-D>. enter then returns you to the
|
||
COHERENT shell.
|
||
|
||
For list-formatted files, it is better to use the enter command than an editor. If you
|
||
do your entry with a text editor, you must include all of the column names, in the
|
||
same order and spelled correctly.
|
||
|
||
Example
|
||
|
||
To add a line to file maillist, type the following:
|
||
|
||
enter maillist
|
||
|
||
The editing session may go as follows:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 221 / Buchseite 211 ====
|
||
enter 211
|
||
|
||
Number 2
|
||
|
||
Name Chiquita Banana
|
||
|
||
Company Standard Brands
|
||
|
||
Street *
|
||
|
||
Company United Brands
|
||
|
||
Street Uno Avenido de la Reforma
|
||
|
||
City San Jose
|
||
State Costa Rica
|
||
ZIP 123456789
|
||
|
||
Phone 1234
|
||
|
||
Name <ctrl-D>
|
||
|
||
Note we made an error entering Company and did not realize it until we were at Street. We
|
||
typed a caret **' that reprompted us for Company, which we then reentered. enter then
|
||
went on to prompt us for Company again.
|
||
|
||
The entered file now appears as follows:
|
||
|
||
Number 1
|
||
|
||
Name Ronald McDonald
|
||
Company McDonald’s
|
||
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
|
||
|
||
Note that the last row (actually eight lines and the bottom newline) is the one we entered.
|
||
Just press <Return> if you have no data to enter after a prompt.
|
||
|
||
Now for an example of entering a table. If you want to add a line to inventory. type:
|
||
|
||
enter inventory
|
||
|
||
Item# Amount Cost Value Description
|
||
|
||
Then start typing your rows. Remember to insert tabs between columns:
|
||
|
||
8 123 5.98 [) widget
|
||
9 29 15.50 t) another widget
|
||
<ctrl-D>
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 222 / Buchseite 212 ====
|
||
212 explode
|
||
|
||
The inventory file now looks like this:
|
||
Item# Amount Cost Value Description
|
||
|
||
1 3 5.00 0 rubber gloves
|
||
2 100 0.50 [¢) test tubes
|
||
|
||
3 5 8.00 0 clamps
|
||
|
||
4 23 1.98 0 plates
|
||
|
||
5 99 2.45 0 cleaning cloth
|
||
6 89 14.75 0 bunsen burners
|
||
7 5 175 0 scales
|
||
|
||
8 123 5.98 0 widget
|
||
|
||
9 29 15.50 0 another widget
|
||
Note that the last two lines are the ones we entered.
|
||
|
||
See Also
|
||
|
||
listtotable, tabletolist, ve
|
||
|
||
explode — /rdb Command
|
||
Produce table of subparts and their count for a part
|
||
explode Part Amount [ table ]
|
||
|
||
The command explode takes a part number or name and looks it up in a part table to find
|
||
all of its subparts. It then finds the subparts of those subparts, and so forth, until it can
|
||
seek no farther. explode also multiplies the number of parts times the subpart counts at
|
||
each interaction, so the final subpart table lists all of the subparts of the original part and
|
||
the total number of subparts needed to make the part.
|
||
|
||
You can use explode to generate a list of all items needed to make a product. The cost of
|
||
these subparts, times the count. gives the value that can be totaled to arrive at the total
|
||
cost of the product.
|
||
|
||
explode assumes that the Part, Subpart, and Count columns are the first three columns of
|
||
the table, and that the third column is actually named Count.
|
||
|
||
Example
|
||
If you had a parttable, like this:
|
||
|
||
Part Subpart Count
|
||
|
||
10001 10010 3
|
||
10001 10020 4
|
||
10010 10100 2
|
||
10020 10100 5
|
||
|
||
and you wanted to find the subpart list and count for two part 10001s, you would type:
|
||
explode 10001 2
|
||
|
||
The result would be:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 223 / Buchseite 213 ====
|
||
explode 213
|
||
|
||
Part Amount
|
||
|
||
10001 2
|
||
10010 6
|
||
10020 8
|
||
10100 52
|
||
|
||
Note that both 10010 and 10020 have 10100 as a subpart, but explode uses subtotal to
|
||
combine the 10100 subparts into one row. The table is also sorted.
|
||
|
||
See Also
|
||
bom, subtotal
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 224 / Buchseite 214 ====
|
||
214
|
||
|
||
fd
|
||
|
||
fd — /rdb Command
|
||
|
||
Test for functional dependency of columns
|
||
fd determinecolumn dependcolumn < table
|
||
|
||
The command fd reads table and tests whether its determinecolumn determines
|
||
dependcolumn. A column in a table functionally depends upon another column when there
|
||
is only one value in the second column for each value in the first. This helps you to
|
||
determine if a table is normalized. (See the section on Normalization, below, for details on
|
||
what this means.)
|
||
|
||
Example
|
||
First let's look at our inventory table:
|
||
|
||
Item Amount Cost Value Description
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
3 5 80 400 clamps
|
||
4 23 19 437 plates
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
y 5 173 875 scales
|
||
|
||
Note that the first column, Item, is the key column for the table. It functionally determines
|
||
all of the other columns. Each value in column Item is unique. so each value determines,
|
||
or is the key, to its row and all of the column values on it.
|
||
|
||
However, column Cost does not functionally depend upon Amount because there are two
|
||
‘5’ values in Amount and each has a different value for Cost associated with it (on the same
|
||
row or line). The common sense (technically called the “semantics”) of the table is that
|
||
knowing the number of items we have in inventory does not tell us how much they cost.
|
||
|
||
Now let's see if fd can find the dependencies. The command
|
||
fd Item Cost < inventory
|
||
|
||
returns the message true. This is correct, because Item is the key column. However, the
|
||
command
|
||
|
||
fd Amount Cost < inventory
|
||
|
||
returns the message false. This, too, is correct.
|
||
|
||
Normalization
|
||
|
||
A key column should aways functionally determine all of the other columns in the table.
|
||
But nonkey columns should not depend upon each other.
|
||
|
||
If there are too few data in the table, a pseudo-dependency may be discovered. Be sure your
|
||
table has lots of data before you test it.
|
||
|
||
To normalize your tables, you must check for functional dependencies. When functional
|
||
dependency is found with non-key columns, the columns should be projected and uniqued
|
||
to form a second table. Then the functionally dependent column, but not the determining
|
||
column, should be removed from the first table. For example:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 225 / Buchseite 215 ====
|
||
filesize 215
|
||
|
||
column columnl column2 < table | uniq > newtable
|
||
column ‘sed 1q table | sed s/column2//‘ < table > tmp
|
||
mv tmp table
|
||
|
||
In the second table, the column that determines the other column is the key for that table.
|
||
If you need to recreate the original first table. you can join the two new tables by using the
|
||
command jointable, as follows:
|
||
|
||
jointable -j columnl table newtable > oldtable
|
||
|
||
Normalization, or simplification, is an important process. Normalized files are smaller and
|
||
are easier to maintain.
|
||
|
||
See Also
|
||
|
||
column, jointable, paste.rdb
|
||
COHERENT Lexicon: cut, false, mv, paste, sed, true
|
||
|
||
filesize — /rdb Command
|
||
|
||
Return the number of characters in a file
|
||
filesize file ...
|
||
|
||
The command filesize displays the number of bytes in each file. It is much faster than the
|
||
COHERENT command we because it uses the system call stat() to get the number from the
|
||
i-node table, rather than counting the bytes in the file.
|
||
|
||
If you ask filesize to size only one file, it sends one number to the standard output. This
|
||
number can be assigned to a shell variable. With more than one file, it produces a table of
|
||
sizes.
|
||
|
||
Example
|
||
The following command returns the size of file filesize.1, which holds the “raw” form of
|
||
what you are reading:
|
||
|
||
filesize filesize.1
|
||
|
||
This displays one value on the standard output, e.g.:
|
||
532
|
||
|
||
The following command asks for the size of files ascii.1 and filesize.1:
|
||
filesize ascii.1 filesize.1
|
||
|
||
This form of the command returns a tabular output, e.g.:
|
||
|
||
Offset Filename
|
||
|
||
464 ascii.1
|
||
532 filesize.1
|
||
See Also
|
||
|
||
COHERENT Lexicon: Is, stat), we
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 226 / Buchseite 216 ====
|
||
216
|
||
|
||
fillform — fixtotable
|
||
|
||
fillform — /act/g] Command
|
||
|
||
Fill a tax from with adjusted trial balance data
|
||
fillform form
|
||
|
||
The command fillform is part of the accounting/general-ledger system included with /rdb.
|
||
It fills in the tax form form, which must be one of 1120 (corporate), 1120S (S corporation),
|
||
C (schedule C), or partnership tax form. It writes its output into a file with the name form.
|
||
|
||
Example
|
||
The following example fills in the S corporation form:
|
||
|
||
fillform 1120s
|
||
|
||
When you post-process the output with the command
|
||
sed 10q 1120S
|
||
|
||
you see output that resembles the following:
|
||
|
||
Taxline Amount Description
|
||
|
||
10la 13500 Sales
|
||
|
||
101b 0 Returns and Allowances
|
||
10lc 13500 Net Sales
|
||
|
||
102 0 Cost of Goods Sold
|
||
102-Al 20000 Beginning Inventory
|
||
102-A2 3601 Misc Merchandise
|
||
102-A3 2100 Salaries and Wages
|
||
102-A4 0 Other Costs
|
||
|
||
See Also
|
||
|
||
calculate
|
||
|
||
COHERENT Lexicon: sed.
|
||
|
||
Notes
|
||
|
||
Please note the tax tables and forms included with /rdb are from 1987. These are
|
||
examples, and no claim is made for their accuracy in computing this year’s taxes. Caveat
|
||
ulilitor.
|
||
|
||
fixtotable — /rdb Command
|
||
|
||
Converts fixed length format to /rdb table format
|
||
fixtotable column[=n1,n2] ... < fixtdb
|
||
|
||
The command fixtotable converts a data base from fixed-length format to variable length
|
||
/rdb format. It does so by selecting n2 bytes of data from table fixtdb, beginning at the n1
|
||
position for each column specified. It inserts tabs between columns and calls the /rdb
|
||
command compress to remove leading and trailing blanks. It generates header records
|
||
from the column names. Column names that do not specify start position (nl) and field
|
||
width (n2) are considered empty columns, and appear as such in the output. Blank records
|
||
are removed.
|
||
|
||
Example
|
||
|
||
For example, let's look at a file named journal:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 227 / Buchseite 217 ====
|
||
foot 217
|
||
|
||
foot —
|
||
|
||
1 10 20 30
|
||
wanntenn|aaantenne|-too=|
|
||
820102101 25000
|
||
820102211.1 25000
|
||
820103150.1 10000
|
||
|
||
820103101 5000
|
||
820103211.2 5000
|
||
820104130 30000
|
||
|
||
The first six bytes are the date field; the next six bytes, starting at position 7 are the
|
||
account number field; the next seven bytes, starting at position 13 are the credit field; and
|
||
the last seven bytes, starting at position 20 are the debit field.
|
||
|
||
The following command yanks the account number and the credit and debit fields from
|
||
journal, makes a new table with a new field for the description:
|
||
|
||
fixtotable Account=7,6 Debit=13,7 Credit=20,7 Description < journal
|
||
This produces the following table:
|
||
Account Debit Credit Description
|
||
|
||
101 25000
|
||
|
||
211.1 25000
|
||
150.1 10000
|
||
|
||
101 5000
|
||
|
||
211.2 5000
|
||
130 30000
|
||
|
||
See Also
|
||
|
||
compress, tabletofix
|
||
|
||
/act/gl Command
|
||
Foot or subtotal Debits and Credit of ledger
|
||
foot
|
||
|
||
The command foot is part of the accounting/general-ledger system included with /rdb. It
|
||
subtotals the accounts in table ledger.
|
||
|
||
Example
|
||
|
||
The command foot produces a table that resembles the following:
|
||
|
||
Account Date Debit Credit Ref Short Description
|
||
1010 851231 1758 cash
|
||
|
||
1010 851231 5137 cash
|
||
|
||
1010 5137 1758
|
||
|
||
3010 1601 deposit sales
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 228 / Buchseite 218 ====
|
||
218 foot
|
||
|
||
850125
|
||
|
||
c1459 royalty book fees
|
||
|
||
LEXICON
|
||
|
||
850103
|
||
850104
|
||
850105
|
||
850106
|
||
|
||
e115 travel
|
||
Vv travel
|
||
e116 travel
|
||
r travel
|
||
|
||
shuttle bus
|
||
meal
|
||
|
||
meal
|
||
|
||
hotel
|
||
|
||
|
||
==== PDF-Seite 229 / Buchseite 219 ====
|
||
getjournal — gregorian 219
|
||
|
||
G
|
||
|
||
getjournal — /act/gl Command
|
||
Copy journals for sales, purchasing, pay systems
|
||
getjournal journalname
|
||
|
||
The command getjournal is part of the accounting/general-ledger system included with
|
||
/rdb. It copies, totals, and adjusts journals from other parts of the business system. These
|
||
subsidiary journals are created automatically by the operations of sales, purchasing, and
|
||
other departments. It also gets the inventory value for the table journaladjust.
|
||
|
||
Example
|
||
|
||
The command
|
||
|
||
getjournal journaldeposit
|
||
|
||
reads the table journaldeposit and prints on the standard output a table that resembles
|
||
the following:
|
||
|
||
Date Amount Account Ref Description
|
||
891231 13500.00 sales deposit from sales/deposit
|
||
See Also
|
||
|
||
act, consolidate
|
||
|
||
gregorian — /rdb Command
|
||
Convert column of dates for arithmetic and format change
|
||
gregorian [ -ceu] [ Column... ] < tableorlist
|
||
|
||
The command gregorian converts Julian dates in one or more Columns to Gregorian date.
|
||
When used with the command julian, you can do the following:
|
||
|
||
1. Add days to a date.
|
||
|
||
2. Subtract days from a date.
|
||
|
||
3. Subtract two dates to find the number of days between them.
|
||
4. Change the format of a date.
|
||
|
||
A Gregorian date is a string that presents the date of the current year, month, and day; for
|
||
example “911231". A Julian date, however, is the number of days since the beginning of
|
||
the Julian calendar (January 1, 4713 BC). This system is used by astronomers, computer
|
||
programmers, and other people who wish to store dates in a form that can be easily
|
||
translated from one system of dating to another, without having to worry about leap years,
|
||
dates of the births of religious figures, etc. Because Julian dates are integers, you can
|
||
subtract one from another to find the number of days between two dates.
|
||
|
||
To perform arithmetic on dates, first use the command julian to convert the dates from
|
||
Gregorian form to Julian. Then, use the command compute to add or subtract the dates
|
||
(or add a constant to a date). Finally. use gregorian to convert the sum or the difference
|
||
back to Gregorian form.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 230 / Buchseite 220 ====
|
||
220 = =gregorian
|
||
|
||
Options
|
||
gregorian recognizes the following options:
|
||
|
||
-c Output computer date format, i.e., YYMMDD. /rdb uses this format by default for its
|
||
Gregorian dates because it can be sorted and selected in correct numerical sequence.
|
||
|
||
-e€ Output European date format. i.e.. DD/MM/YY.
|
||
-u Output U.S. date format, i.e.. MM/DD/YY.
|
||
|
||
Example
|
||
|
||
The first example shows how to add dates. Suppose we have a file called journal. as
|
||
follows:
|
||
|
||
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
|
||
|
||
Now, suppose that we want to add 45 days to each of the dates. First, see what julian does.
|
||
Typing
|
||
julian Date < journal
|
||
prints the following on the standard output:
|
||
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
|
||
|
||
The Date column now holds a Julian date. Note we gave no option because computer
|
||
format is the default.
|
||
|
||
The next command adds 45 days to each entry in the Date column:
|
||
julian Date < journal | compute ‘Date += 45’ | gregorian Date
|
||
|
||
This command prints the following on the standard output:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 231 / Buchseite 221 ====
|
||
gregorian 221
|
||
|
||
870205
|
||
870205
|
||
870206
|
||
870206
|
||
870206
|
||
870207
|
||
870207
|
||
870207
|
||
|
||
Account Debit
|
||
|
||
130 30000
|
||
|
||
25000
|
||
|
||
5000
|
||
5000
|
||
|
||
15000
|
||
15000
|
||
|
||
Description
|
||
|
||
cash from loan
|
||
|
||
loan number #378-14 Bank Amerigold
|
||
test equipment from Zarkoff
|
||
|
||
cash payment
|
||
|
||
note payable to Zarkoff Equipment
|
||
inventory - parts from CCPSC
|
||
accounts payable to CCPSC
|
||
|
||
cash payment to CCPSC for parts
|
||
|
||
As you can see, every date is now 45 days later than they originally were.
|
||
|
||
The next example converts one format of Gregorian date to another. To convert the Date
|
||
column in our example table from computer format to U.S. format, type the following:
|
||
|
||
julian Date < journal | gregorian -u Date | justify Date
|
||
|
||
The result is as follows:
|
||
|
||
Date
|
||
|
||
12/22/86 101
|
||
12/22/86 211.1
|
||
12/23/86 150.1
|
||
12/23/86 101
|
||
12/23/86 211.2
|
||
12/24/86 130
|
||
12/24/86 201.1
|
||
12/24/86 101
|
||
|
||
30000
|
||
|
||
Credit Description
|
||
cash from loan
|
||
25000 loan number #378-14 Bank Amerigold
|
||
test equipment from Zarkoff
|
||
5000 cash payment
|
||
5000 note payable’to Zarkoff Equipment
|
||
inventory - parts from CCPSC
|
||
15000 accounts payable to CCPSC
|
||
15000 cash payment to CCPSC for parts
|
||
|
||
Because the U.S. format is two characters wider than the computer format, we included the
|
||
command justify in our command line to line things up.
|
||
|
||
See Also
|
||
compute, computedate, julian
|
||
COHERENT Lexicon: awk, date
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 232 / Buchseite 222 ====
|
||
222 ~hashkey — head line
|
||
|
||
hashkey — /rdb Command
|
||
|
||
Return the hash offset for key strings
|
||
|
||
hashkey rows keystring ...
|
||
|
||
The command hashkey adds the ASCII value of each character in the keystrings (except
|
||
spaces or tabs), and returns the modulo of rows. This is for computing the hash offset into
|
||
hash-index table for the hash fast-access method. It is used by the command append to
|
||
|
||
update the hash-index table.
|
||
Example
|
||
|
||
Here we convert several characters. The command
|
||
|
||
hashkey 11 ABCD
|
||
|
||
returns 2. (That is, ASCII values 65 plus 66 plus 67 plus 68 yields 266; which. when
|
||
divided by 11 yields a remainder of 2). The command
|
||
|
||
hashkey 29 abcdefg
|
||
|
||
returns 4.
|
||
|
||
See Also
|
||
|
||
append ascii, chr
|
||
COHERENT Lexicon: ASCII
|
||
|
||
head line — /rdb Definition
|
||
|
||
The head line is the first line in an /rdb table. It names each column in the table. Each
|
||
entry in the head line must be separated by a tab character.
|
||
|
||
Description
|
||
|
||
rubber gloves
|
||
|
||
test tubes
|
||
clamps
|
||
|
||
plates
|
||
cleaning cloth
|
||
bunsen burners
|
||
scales
|
||
|
||
Example
|
||
|
||
The table inventory appears as follows:
|
||
|
||
Item Amount Cost Value
|
||
zf 3 50 150
|
||
2 100 5 500
|
||
3 5 80 400
|
||
4 23 19 437
|
||
5 99 24 2376
|
||
6 89 147 13083
|
||
7 s 175 875
|
||
|
||
The first line
|
||
|
||
Item Amount Cost Value
|
||
|
||
is this table's head line.
|
||
|
||
See Also
|
||
dash line, listtotable, tabletolist
|
||
|
||
LEXICON
|
||
|
||
Description New
|
||
|
||
==== PDF-Seite 233 / Buchseite 223 ====
|
||
headoff —headon 223
|
||
|
||
headoff — /rdb Command
|
||
Remove an /rdb head from both table and list files
|
||
headoff < tableorlist
|
||
|
||
The command headoff “beheads” tableorlist; that is, it strips off its header. Tables have
|
||
two-line colurnn heads; list files have only one line that consists of a single newline
|
||
character. The COHERENT command tail +3 does the same thing for a table; and tail +2
|
||
for a list. 7
|
||
|
||
The command union uses headoff to assemble files. Only the first file keeps its head.
|
||
Example
|
||
To behead the table inventory, type:
|
||
|
||
headoff < inventory
|
||
|
||
This writes something like the following on the standard output:
|
||
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
|
||
3 5 80 400 clamps
|
||
|
||
4 23 19 437 plates
|
||
|
||
| 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
See Also
|
||
|
||
headon, insertdash, union
|
||
COHERENT Lexicon: head, tail
|
||
|
||
headon — /rdb Command
|
||
|
||
Add an /rdb header to a table
|
||
headon < table
|
||
|
||
The command headon appends an /rdb header onto table. Tables have a two-line column
|
||
head. When you have a table without an /rdb header, perhaps created by another program,
|
||
you can add a head to it. You can also do this in a pipe and send the new table to other
|
||
/rdb commands for processing.
|
||
|
||
Example
|
||
If you want to treat the file /etc/passwd as a table for /rdb command processing, use
|
||
headon, as follows:
|
||
|
||
i a A ' < /etc/passwd | headon | justify
|
||
|
||
Note the use of the COHERENT command tr to translate a colon *:' into a tab character; and
|
||
the use of the /rdb command justify to align the columns. This produces something like
|
||
the following:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 234 / Buchseite 224 ====
|
||
224
|
||
|
||
helpme — howmany
|
||
|
||
root
|
||
daemon
|
||
bin
|
||
uucp
|
||
ip
|
||
guest
|
||
rod
|
||
|
||
dVAYxSsJy10Fg
|
||
|
||
rVOhF4 9RpZXEY
|
||
|
||
Be sure the first line of the table has no blank fields or headon counts the wrong number of
|
||
|
||
fields.
|
||
See Also
|
||
|
||
3 4 5 6
|
||
|
||
0 3 Super User /
|
||
|
||
1 12 background /
|
||
|
||
2 2 binary programs /bin
|
||
|
||
5 1 uucP /usr/lib/uucp
|
||
71 2 Line Printer /usr/spool/1p
|
||
100 100 Guest User /usr/guest
|
||
|
||
0 0 Rod Manis /usr/rod
|
||
|
||
headoff, insertdash, justify, rmblank
|
||
COHERENT Lexicon: passwd, tr
|
||
|
||
helpme — /rdb Command
|
||
List the help commands available
|
||
|
||
helpme
|
||
|
||
The command helpme lists all other /rdb help commands.
|
||
|
||
Example
|
||
|
||
Typing helpme prints the following on the standard output:
|
||
|
||
Command
|
||
|
||
“commands”
|
||
|
||
“whatis command"
|
||
“whatwill feature"
|
||
“man command”
|
||
|
||
howmany — /rdb Command
|
||
Display the number of commands in a directory
|
||
|
||
howmany
|
||
|
||
The command howmany displays the number of the commands it finds in directory
|
||
|
||
SRDB/bin.
|
||
|
||
See Also
|
||
rdb, whatis, whatwill
|
||
|
||
LEXICON
|
||
|
||
Description
|
||
a menu with some commands
|
||
|
||
a list of the available commands
|
||
description and syntax of all the commands
|
||
description and syntax of command
|
||
|
||
info on commands with that feature
|
||
|
||
the manual page for that command
|
||
|
||
|
||
==== PDF-Seite 235 / Buchseite 225 ====
|
||
index 225
|
||
|
||
index — /rdb Command
|
||
Set up table for search
|
||
index [-m{bhirs]] [-x] [-hsl [2> location]] tableorlist [keycol ...] [ < keytable ]
|
||
|
||
The command index sets up a table for the program search. The indexing it performs
|
||
increases the speed with which search can find a row in a table or list file. This is very
|
||
important for large files.
|
||
|
||
Exactly what index does depends upon the method of indexing you choose. For some
|
||
methods, it builds another table, called a secondary index file, that the specified method
|
||
requires. It is possible to index one file by all five methods. Some methods can index all of
|
||
a table's columns.
|
||
|
||
Please note that these fast-access methods are static. If the table or list is changed — by a
|
||
text editor, for example — it may have to be reindexed. Applications should manipulate the
|
||
table or list files and their secondary index to update them together. Forms packages
|
||
should dynamically maintain these files.
|
||
|
||
There is a trick to allow you to index any or all of the columns in a file. Simply use the
|
||
COHERENT command In to link the file to as many different names as you have columns to
|
||
index. Then index the table through each of its link aliases. For details, see the
|
||
COHERENT Lexicon’s entry for In.
|
||
|
||
Options
|
||
The following options control the method of indexing that index produces:
|
||
-m Index using the default method, which is sequential. See -ms, below.
|
||
|
||
-mb Binary indexing. index simply sorts the file on the specified key column. No
|
||
secondary file is created. Because a file can only be sorted on one column, only one
|
||
column can be indexed using this method. The command sorttable gives the same
|
||
result as this option.
|
||
|
||
-mh Hash indexing. index builds a secondary-index file, named tableorlist.h, hashes
|
||
all of the key-column’s values, and writes them and their offsets to the secondary-
|
||
index file. Please note that because the COHERENT system places a limit of 14
|
||
characters on a file name, the name of tableorlist must not exceed 12 characters, or
|
||
index will not be able to name correctly the secondary-index file.
|
||
|
||
-mi Inverted or indexed indexing. index builds a secondary-index file of keys and
|
||
offsets, then sorts on the keys. The secondary file is named tableorlist.i. The trick
|
||
to index more than one column, previously discussed, alsos work for the inverted
|
||
method.
|
||
|
||
If you plan on using the incomplete-match feature of search (which works only with
|
||
the inverted method), you must specify the -x flag, so the secondary index is sorted
|
||
|
||
properly.
|
||
|
||
-mr Record-number indexing. index builds a secondary file named (tableorlist.r, which
|
||
is one fixed-length column of row offsets.
|
||
|
||
-ms Sequential or linear indexing. index does nothing in this case, because search
|
||
simply looks through the whole file.
|
||
|
||
The following options control details of index's output:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 236 / Buchseite 226 ====
|
||
226
|
||
|
||
index
|
||
|
||
-h No head line on the output table.
|
||
|
||
-l Write to the standard error the starting and stopping location of each row, and the
|
||
offset entry in the secondary-index file. These numbers are used by the commands
|
||
replace, lock, and unlock. The command seek uses this option to find the
|
||
locations of rows. The locations are sent to standard-error device, which under the
|
||
Bourne and Korn shells is file descriptor 2; thus, you can redirect them into a file
|
||
by using the shell operator 2>. You can store these data until they are needed by
|
||
your shell programs.
|
||
|
||
This option produces four integers. If there is no secondary-index file, the start
|
||
location is zero.
|
||
|
||
-s Only one row is found. This speeds up some of the methods because they do not
|
||
have to continue searching after they find the first match. The sequential method
|
||
will, on average, run twice as fast; whereas the hash, binary, and inverted methods
|
||
will run slightly faster. The record-access method will not change, as it only finds
|
||
one match anyway.
|
||
|
||
Methods and Suffixes
|
||
|
||
The following gives suffixes that index appends to names of tables, in order to name its
|
||
secondary-index files.
|
||
|
||
Method Suffix Example
|
||
-b None a4
|
||
|
||
-h -h inventory.h
|
||
-i ol inventory.i
|
||
-r r inventory.r
|
||
-s None
|
||
|
||
Example
|
||
|
||
Let's look at the first ten lines of an accounts chart, named chart:
|
||
|
||
Account Name
|
||
|
||
100 Assets
|
||
|
||
101 Cash
|
||
|
||
111 Accounts Receivable
|
||
111.1 Allowance for Bad Debt
|
||
115 Notes Receivable
|
||
|
||
120 Deposits
|
||
|
||
130 Parts Inventory
|
||
|
||
150 Equipment
|
||
|
||
Access to the data in chart can be sped up by indexing it and using the command search to
|
||
find the row you want. To index chart using the binary (sorted) search method, type:
|
||
|
||
index -mb chart Account
|
||
|
||
index quietly returns when it finishes. You are now ready to use search to find an Account
|
||
number in the chart
|
||
See Also
|
||
|
||
append, delete, lock, replace, search, unlock, update
|
||
COHERENT Lexicon: In
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 237 / Buchseite 227 ====
|
||
insertdash — intersect 227
|
||
|
||
insertdash — /rdb Command
|
||
Insert dash line as second line in table
|
||
insertdash < table-without-dashline
|
||
|
||
The command insertdash writes a line of dashes (hyphens) as the second line of the table.
|
||
It makes the dash line by copying the head line and turning every character in the first into
|
||
a hyphen except the tabs.
|
||
|
||
This command is useful for files created by the system or non-COHERENT programs that do
|
||
not have the dash line. However, you will also need to convert field separators into tabs.
|
||
You can do this with the COHERENT commands tr or sed.
|
||
|
||
Example
|
||
|
||
insertdash assumes a table that resembles the following:
|
||
|
||
Item Amount Cost Value Description
|
||
1 3 50 150 rubber gloves
|
||
|
||
After running insertdash on it. this table looks like this:
|
||
|
||
Item Amount Cost Value Description
|
||
|
||
1 3 50 150 rubber gloves
|
||
See Also
|
||
dashline, headoff, headon
|
||
|
||
COHERENT Lexicon: sed, tr
|
||
|
||
intersect — /rdb Command
|
||
Write table of rows that are in both input tables
|
||
intersect lable] table2
|
||
|
||
The command intersect is a shell script that uses the COHERENT commands sort and
|
||
uniq to perform a logical AND on two tables. It produces a new table that consists only of
|
||
the rows that are in both of the input tables. The two input tables must have the same
|
||
number of columns (called union compatible), and rows must match exactly to be considered
|
||
|
||
the same.
|
||
|
||
Example
|
||
|
||
Consider the table journal, which appears as follows:
|
||
|
||
Date Amount Account Ref Description
|
||
|
||
820107 14.00 meal v meal with jones
|
||
|
||
820114 81.80 insur c car insurance allstate
|
||
|
||
820119 81.72 vitamin c sundown vitamins
|
||
|
||
820121 20.83 meal Vv meal with scott
|
||
|
||
820121 2500.00 keogh cog keogh payment
|
||
|
||
820125 99.00 dues Vv dues to uni-ops unix conference
|
||
|
||
And consider the table carexpense. which appears as follows:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 238 / Buchseite 228 ====
|
||
228 ~—s invoice
|
||
|
||
Date Amount Account Ref Description
|
||
|
||
820113 101.62 car v car repairs
|
||
|
||
820114 81.80 insur c car insurance allstate
|
||
820114 93.00 car c car registration dmv
|
||
|
||
To see if any rows in journal are also in carexpense, type the command:
|
||
intersect journal carexpense
|
||
In this example, you would see the following on the standard output:
|
||
|
||
Date Amount Account Ref Description
|
||
|
||
820114 81.80 insur c car insurance allstate
|
||
|
||
As you can see, the insurance expense was already posted to the general journal.
|
||
|
||
See Also
|
||
|
||
difference, jointable, union
|
||
COHERENT Lexicon: sort, uniq
|
||
|
||
invoice — /act/sales Command
|
||
Print invoice for a sale order
|
||
invoice
|
||
|
||
The command invoice is part of the accounting/sales system that is included with /rdb. It
|
||
prompts for the number of a sales order and then prints an invoice for that order.
|
||
|
||
Example
|
||
|
||
The following walks you through an example session with invoice:
|
||
|
||
Please enter order number (or Return to exit): 1
|
||
Invoice
|
||
|
||
Makeapile, Inc., 123 Bigbucks Blvd., Dallas, TX 12345, 1-800-SOF-WARE
|
||
|
||
Order Number 1
|
||
Date Ordered 850723
|
||
Date Shipped fo)
|
||
|
||
Mailing Address for Customer Number 2
|
||
Customer Number 2
|
||
Mr. Thomas Boomer President
|
||
|
||
Ye Olde Thermonuclear Bombe Shoppe
|
||
54321 Blooy Road
|
||
|
||
Livermore, California USA
|
||
Order Number Code Backord Qty Price Total Name
|
||
1 1 rdb 10 1 1500 1500.00 /rdb
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 239 / Buchseite 229 ====
|
||
invoice 229
|
||
|
||
Gross 1500.00
|
||
Tax 75.00
|
||
Total 1575.00
|
||
|
||
Please enter order number (or Return to exit):
|
||
|
||
See Also
|
||
|
||
act, cstate
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 240 / Buchseite 230 ====
|
||
230
|
||
|
||
jointable
|
||
|
||
jointable — /rdb Command
|
||
|
||
Join two tables into one where keys match
|
||
|
||
jointable [-a[1 |2)] [-j[1]2] column)... -n -] table! [table2]
|
||
|
||
The command jointable joins table] to table2 on column, which is common to both tables
|
||
(called the key column). If no column is named, jointable assumes that the first column in
|
||
each table is the key column.
|
||
|
||
Each table must be sorted on the key column. jointable writes a new table that has one
|
||
row for the rows in the tables whose values in the key column match. The columns of the
|
||
new table are all the columns in table] followed by all the columns in table2— with the sole
|
||
exception that the key column is not repeated.
|
||
|
||
This is called a natural join. An equi-join repeats the key column.
|
||
|
||
The COHERENT system's command join will also join two tables in the manner described
|
||
above, but it does not know about /rdb head lines.
|
||
|
||
String vs. Numeric Sort
|
||
|
||
The commonest problem seen with jointable is when users attempt to join tables that have
|
||
been sorted numerically on the key columns (that is, the columns that the tables are going
|
||
to be joined on). They use sorttable with the -n option (for numeric) to sort a table, then
|
||
call jointable. jointable, however, expects to see a string sort fails to join the tables
|
||
correctly.
|
||
|
||
The following compares a string sort with a numeric sort:
|
||
|
||
String Numeric
|
||
1 1
|
||
10 2
|
||
2 10
|
||
20 20
|
||
|
||
Can you see why? Numeric is the way we count and is obviously correct. But string sort
|
||
looks at the first character, then the second. A space sorts ahead of ‘0’, so ‘1’ comes before
|
||
“10”. More importantly, ‘1’ comes before ‘2' regardless of the characters to the right. That is
|
||
why “10” comes before "2" followed by a space. This problem shows up as empty output
|
||
from a jointable, when you know some of the rows should be joined.
|
||
|
||
Right-justification makes numeric and string sorts the same. The leading spaces help the
|
||
string sort to sort numbers correctly.
|
||
|
||
To make it easy for users to avoid this problem, jointable has the option -n, for symmetry
|
||
with the COHERENT command sort.
|
||
|
||
If you want to join two tables through a numeric key column, you must either call the
|
||
sorttable without its -n numeric sort option. so that it defaults to string sort: or if you use
|
||
the -n option for sorttable, be sure to use it also with jointable.
|
||
|
||
Options
|
||
jointable recognizes the following options:
|
||
|
||
-an All or one of the files (1 or 2) is output, whether it matches or not. In addition to
|
||
the normal output, jointable produces a line for each unpairable line in file n,
|
||
where nis 1 or 2. For example, the command
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 241 / Buchseite 231 ====
|
||
jointable 231
|
||
|
||
jointable -al ledger chart
|
||
|
||
forces jointable to print every row in table ledger. regardless of whether any value
|
||
in ledger’s Account column matches any value in chart’s Account column.
|
||
|
||
-jn column
|
||
|
||
Join on the column column in table number n. If n is missing, use the column
|
||
column in each table. For example, the command
|
||
|
||
jointable -j1 Account -j2 account ledger chart
|
||
|
||
joins tables ledger and chart using the Account column in ledger and the account
|
||
column in chart. If no columns are specified with this option, jointable joins the
|
||
tables by the first column in each. Thus, this option lets you join on any column
|
||
defined in either file. even when they have different names and locations.
|
||
|
||
Numeric join. This means that tablel and table2 were sorted with the numeric
|
||
option -n. Remember that if you use -n with the command sorttable, you must also
|
||
use it with jointable.
|
||
|
||
Read the standard input in place of a table. For example, the command
|
||
|
||
sorttable < journal | jointable - chart
|
||
|
||
means to sort table journal, then join it with table chart so that journal is on the
|
||
left of the output table and chart is on the right.
|
||
|
||
Note that this option is used only in place of tablel. If table2 is absent from the
|
||
command line, jointable automatically reads the standard input for that table’s
|
||
data.
|
||
|
||
_Note that most of these options are about the same as for the COHERENT command join.
|
||
Example
|
||
|
||
Consider table chart. as follows:
|
||
|
||
Account Name
|
||
|
||
Assets
|
||
|
||
Cash
|
||
|
||
Accounts Receivable
|
||
Allowance for Bad Debt
|
||
Notes Receivable
|
||
Deposits
|
||
|
||
Parts Inventory
|
||
|
||
and table ledger. as follows:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 242 / Buchseite 232 ====
|
||
232
|
||
|
||
jointable
|
||
|
||
Account Date Debit Credit
|
||
|
||
101 820102 25000
|
||
101 820103 5000
|
||
101 820104 15000
|
||
130 820104 30000
|
||
|
||
150.1 820103 10000
|
||
201.1 820104 15000
|
||
211.1 820102 25000
|
||
211.2 820103 5000
|
||
|
||
Note that each is sorted in string fashion on its first column. To join them, use the
|
||
command:
|
||
|
||
jointable ledger chart
|
||
|
||
This joins the tables on the first column in each, and writes the following to the standard
|
||
output:
|
||
|
||
Account Date Debit Credit Name
|
||
|
||
101 820102 25000 Cash
|
||
|
||
101 820103 5000 Cash
|
||
|
||
101 820104 15000 Cash
|
||
|
||
130 820104 30000 Parts Inventory
|
||
|
||
150.1 820103 10000 Test equipment
|
||
|
||
211.1 820102 25000 Notes Payable - BA
|
||
211.2 820103 5000 Notes Payable - Z Equip
|
||
|
||
As you can see, column Name has been added to the columns of the ledger table, and that
|
||
column Account is not repeated. Also note that jointable wrote only the rows whose values
|
||
in column Account match. If a table has several rows with repeated key values (e.g., the
|
||
three 101s in the Account column), the joined table’s rows are also repeated (see the three
|
||
Cashs in column Name).
|
||
|
||
If you have a table named journal that is sorted on column Account, as follows
|
||
|
||
Date Account Debit Credit
|
||
|
||
820104 101
|
||
|
||
820103 101
|
||
|
||
820102 101 25000
|
||
|
||
820104 130 30000
|
||
|
||
820103 150.1 10000
|
||
|
||
820104 201.1 15000
|
||
820102 211.1 25000
|
||
820103 211.2 5000
|
||
|
||
you could join it with table chart by typing this command:
|
||
jointable -j Account journal chart
|
||
|
||
The following gives another way for the same result (because chart’s join column defaults to
|
||
column 1):
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 243 / Buchseite 233 ====
|
||
jointable 233
|
||
|
||
jointable -j1 Account journal chart
|
||
Both commands produce the following output:
|
||
Date Account Debit Credit Name
|
||
|
||
820104 101 15000 Cash
|
||
|
||
820103 101 5000 Cash
|
||
|
||
820102 101 25000 Cash
|
||
|
||
820104 130 30000 Parts Inventory
|
||
|
||
820103 150.1 10000 Test equipment
|
||
|
||
820102 211.1 25000 Notes Payable - Bank of Amerigold
|
||
820103 211.2 5000 Notes Payable - Z Equipment
|
||
|
||
The -a option lets you see all of one table whether or not there is a match. For example, the
|
||
command
|
||
|
||
jointable -al ledger chart
|
||
writes the following:
|
||
Account Date Debit Credit Name
|
||
|
||
101 820102 15000 Cash
|
||
|
||
101 820103 5000 Cash
|
||
|
||
101 820104 25000 Cash
|
||
|
||
130 820104 30000 Parts Inventory
|
||
|
||
150.1 820103 10000 Test equipment
|
||
|
||
201.1 820104 15000
|
||
|
||
ehh | 820102 25000 Notes Payable - Bank of Amerigold
|
||
211.2 820103 5000 Notes Payable - Z Equipment
|
||
|
||
Note that column Account’s value 201.1 in the ledger shows up here, even though it is not
|
||
in chart. This shows us that 201.1 is an error. All account numbers should be in the chart
|
||
of accounts. We should either add 201.1 to the chart of accounts, or find the correct
|
||
number in the chart of accounts and replace 201.1 in the journal with the correct account
|
||
number.
|
||
|
||
If you pipe a file into a jointable, you can control which table it will be (first or second) by
|
||
using the dash option. For example:
|
||
|
||
sorttable Account < journal | jointable -j Account - chart
|
||
This produces the following output:
|
||
|
||
Date Account Debit Credit Name
|
||
|
||
820103 101 5000 Cash
|
||
|
||
820104 101 15000 Cash
|
||
|
||
820102 101 25000 Cash
|
||
|
||
820104 130 30000 Parts Inventory
|
||
|
||
820103 150.1 10000 Test equipment
|
||
|
||
820102 211.1 25000 Notes Payable - Bank of Amerigold
|
||
820103 211.2 5000 Notes Payable - Z Equipment
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 244 / Buchseite 234 ====
|
||
234
|
||
|
||
julian — justify
|
||
|
||
Note the - before chart. It says that the standard input file will be file 1 or on the left side of
|
||
the table.
|
||
See Also
|
||
|
||
column, sorttable
|
||
COHERENT Lexicon: join
|
||
|
||
julian — /rdb Command
|
||
|
||
Convert column of dates for arithmetic and format change
|
||
julian [ -ceu] [ Column... ] < tableorlist
|
||
|
||
The command julian converts Gregorian dates in one or more columns to Julian format.
|
||
For details on the differences between Gregorian and Julian dates, and how to use these
|
||
commands in scripts, see the manual entry for the command gregorian.
|
||
|
||
See Also
|
||
|
||
computedate, gregorian, todaydate
|
||
|
||
justify — /rdb Command
|
||
|
||
Left or right justify the columns of a table
|
||
justify [-elrct'c’] [ column ... ] < table
|
||
|
||
The command justify right-justifies the columns that contain only numbers, and left-
|
||
justifies the columns that contain any nonnumeric characters. It also lines up floating-
|
||
point numbers on their decimal points.
|
||
|
||
justify improves the appearance of a table. This makes it easier for you to read and edit. It
|
||
also makes a column of variable-length strings into one length, by padding each string with
|
||
Spaces on the right. Note that the extra spaces inserted to improve a table's appearance
|
||
could easily double or triple the size of the table. This increased size not only takes up disk
|
||
space, but slows processing of table. You must decide whether appearance or size is more
|
||
important.
|
||
|
||
Options
|
||
justify recognizes the following options:
|
||
|
||
-e Expand the column to the next tab stop. Ordinarily, a column is only as wide as
|
||
the widest data or column name. This improves the appear, but increases the size
|
||
of the file.
|
||
|
||
The following options override the default justifications (left-justify character strings, right-
|
||
justify numbers):
|
||
|
||
-l (This is the letter “el", not the number one.) Left-justify all named columns.
|
||
-c Center all named columns.
|
||
r Right justify all named columns.
|
||
|
||
These options are sticky, meaning that if you follow an 1, c, or r option with several column
|
||
names, each is treated according to the option. For example, -1 Description Account left
|
||
justifies both Account and Description, regardless of the data each contains.
|
||
|
||
-t’c Use the character ¢ as the column separator instead of tab. c can be any ASCII
|
||
character. Note, however, that once you process a table with this option, you can
|
||
no longer use /rdb commands on it. because all /rdb commands require tabs as
|
||
column separators. See the command trim for a discussion of how you can protect
|
||
special characters from the shell.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 245 / Buchseite 235 ====
|
||
justify 235
|
||
|
||
Example
|
||
|
||
One use of justify is to align columns. Variable-length character columns (like names and
|
||
descriptions) destroy the alignment of columns. For example, notice how the variable-
|
||
length names cause the tabs to break at different points in the following table:
|
||
|
||
Name Credit
|
||
|
||
Anderson 23.49
|
||
Ho 145.98
|
||
Johnson 1.15
|
||
|
||
One solution is to move the variable length column to the last column:
|
||
column Credit Name < credit
|
||
|
||
The table now appears as follows:
|
||
Credit Name
|
||
|
||
23.49 Anderson
|
||
145.98 Ho
|
||
1.15 Johnson
|
||
|
||
Another solution is to use justify to right-pad the Name column, and (while we're at it)
|
||
align the floating point number in the Credit:
|
||
|
||
Name Credit
|
||
|
||
Anderson 23.49
|
||
Ho 145.98
|
||
Johnson 1.15
|
||
|
||
Remember that the file is now larger. All of those extra blank spaces can double or triple
|
||
the size of your file.
|
||
|
||
It is easier to enter the initial data into a table without the padding characters. Then you
|
||
can use justify to pretty up the table.
|
||
|
||
When using the command Iisttotable to convert a list-format file to a table, you may wish
|
||
to use justify to make the resulting table readable.
|
||
|
||
See Also
|
||
column, compresss, listtotable, trim
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 246 / Buchseite 236 ====
|
||
236 —label
|
||
|
||
label — /rdb Command
|
||
|
||
Print mailing labels from a mailing list
|
||
label < list
|
||
|
||
The command label prints mailing labels from a mailing list, in list format. This command
|
||
is obsolete because the command report can make labels more easily; but it is is retained
|
||
as an example of shell programming.
|
||
|
||
label is a shell script so you can change it easily to handle different lists and labels.
|
||
|
||
Example
|
||
If you had a file called maillist that looked like this:
|
||
|
||
Number 1
|
||
|
||
Name Ronald McDonald
|
||
Company McDonald’s
|
||
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
|
||
The command
|
||
label < maillist
|
||
generates mailing labels that look like this:
|
||
|
||
Ronald McDonald
|
||
McDonald’s
|
||
|
||
123 Mac Attack
|
||
Memphis, TENN 30000
|
||
|
||
Chiquita Banana
|
||
|
||
United Brands
|
||
|
||
Uno Avenido de la Reforma
|
||
|
||
San Jose, Costa Rica 123456789
|
||
|
||
See Also
|
||
letter, report
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 247 / Buchseite 237 ====
|
||
length — letter 237
|
||
|
||
length — /rdb Command
|
||
Return the length of its argument or input file
|
||
length [string] [<_file]
|
||
|
||
The command length outputs the number of characters in its first argument. If there is no
|
||
argument, it reads the standard input.
|
||
|
||
Because length counts only its first argument, you must put quotation marks around all of
|
||
the words on the command line to make them one argument.
|
||
|
||
length uses we -c to do the counting.
|
||
|
||
Example
|
||
Here we find the length of a string and a file.
|
||
|
||
length aAl
|
||
This returns 3.
|
||
The next command
|
||
length ‘word1 word2’
|
||
returns 11 — that is, the length of word1 plus word2 plus the space between them.
|
||
The final example measures the number of characters in file length.1:
|
||
length < length.1
|
||
Note that you need must quote strings if they have spaces or tabs in them.
|
||
See Also
|
||
COHERENT Lexicon: we
|
||
|
||
letter — /rdb Command
|
||
Print form letters from a mailing list
|
||
letter letter.1 ... < maillist
|
||
|
||
The command letter prints form letters from a standard letter and a mailing list. It is
|
||
obsolete, because the command report is so much more powerful and easier to use; but it
|
||
is retained for compatibility and as an example of shell programming.
|
||
|
||
letter is a shell script. so you can be easily changed it to handle different lists and letters.
|
||
To modify it, copy letter from $RDB/bin/letter to your local directory, then use your text
|
||
editor to edit it. Then you can modify it with a text editor to handle any special features of
|
||
your mailing list and letters.
|
||
|
||
Example
|
||
If you have a file called maillist that looks like this:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 248 / Buchseite 238 ====
|
||
238 letter
|
||
|
||
Name Ronald McDonald
|
||
Company McDonald’s
|
||
Street 123 Mac Attack
|
||
City Memphis
|
||
|
||
State TENN
|
||
|
||
ZIP 30000
|
||
|
||
Phone (111) 222-3333
|
||
|
||
Name Chiquita Banana
|
||
|
||
Company United Brands
|
||
|
||
Street Uno Avenido de la Reforma
|
||
city San Jose
|
||
|
||
State Costa Rica
|
||
|
||
ZIP 123456789
|
||
|
||
Phone 1234
|
||
|
||
Assume, too, that the two parts of your letter are in two files. letter.1 contains:
|
||
We have a new product that we want to sell to everyone at
|
||
|
||
And letter.2 contains:
|
||
|
||
Please have everyone send us an order. We wil? be very grateful.
|
||
Sincerely,
|
||
|
||
Mr. Marketing
|
||
Makeapile, Inc.
|
||
|
||
To assemble the letter files and the mailing list into one set of mail-merged letters, type the
|
||
following command:
|
||
|
||
letter letter.1 letter.2 < maillist
|
||
This produces:
|
||
|
||
Ronald McDonald
|
||
McDonald‘s
|
||
|
||
123 Mac Attack
|
||
Memphis, TENN 30000
|
||
Dear Ronald McDonald:
|
||
|
||
We have a new product that we want to sell to everyone at
|
||
McDonald’s, Please have everyone send us an order. We will be
|
||
very grateful.
|
||
|
||
Sincerely,
|
||
|
||
Mr. Marketing
|
||
Makeapile, Inc.
|
||
|
||
<... spaces to bottom of letter ... >
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 249 / Buchseite 239 ====
|
||
like — listtosh 239
|
||
|
||
Chiquita Banana
|
||
|
||
United Brands
|
||
|
||
Uno Avenido de la Reforma
|
||
|
||
San Jose, Costa Rica 123456789
|
||
|
||
Dear Chiquita Banana:
|
||
|
||
We have a new product that we want to sell to everyone at United
|
||
Brands. Please have everyone send us an order. We will be very
|
||
grateful.
|
||
|
||
Sincerely,
|
||
Mr. Marketing
|
||
Makeapile, Inc.
|
||
|
||
<... spaces to bottom of letter ... >
|
||
|
||
The following sample letter program prints out the mailing name and address, and the
|
||
salutation Dear Name. It then cats letter.1. echos the company name, and finally cats
|
||
letter.2. letter writes its output to temporary file TMP, then nroffs the TMP file to the
|
||
standard output. nroff reformats the file (left and right justified) for each company name's
|
||
length.
|
||
|
||
By studying the letter shell script and the COHERENT shell’s documentation (sh or ksh),
|
||
you can assemble fancy, complex form letters.
|
||
See Also
|
||
|
||
label, report
|
||
COHERENT Lexicon: cat, ksh, nroff, troff, sh
|
||
|
||
like — /rdb Command
|
||
Find names that sound like another name
|
||
like similar-name file [ name-column ]
|
||
|
||
The command like converts a name to Knuth’s soundex code and looks it up in the .x
|
||
secondary-index file of a name. To work, you must have first run the command soundex, to
|
||
create the soundex file.
|
||
|
||
Example
|
||
See soundex for examples.
|
||
|
||
See Also
|
||
|
||
soundex
|
||
|
||
listtosh — /rdb Command
|
||
Convert list format to shell variable
|
||
listtosh < list
|
||
|
||
The command listtosh converts a list-format file (column<tab>data) to a shell variable
|
||
format (VARIABLE='value’). You can use this to move a record into a shell variable.
|
||
|
||
Example
|
||
Consider file maillist:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 250 / Buchseite 240 ====
|
||
240
|
||
|
||
listtotable
|
||
|
||
Number 1
|
||
|
||
Name Ronald McDonald
|
||
Company McDonald’s
|
||
Street 123 Mac Attack
|
||
City Menphis
|
||
|
||
State TENN
|
||
|
||
ZIP 30000
|
||
|
||
Phone (111) 222-3333
|
||
|
||
Number 2
|
||
|
||
Name Chiquita Banana
|
||
|
||
Company United Brands
|
||
|
||
Street Uno Avenito De La Revolution
|
||
City San Jose
|
||
|
||
State Costa Rica
|
||
|
||
ZIP 123456789
|
||
|
||
Phone 1234
|
||
|
||
The command
|
||
eval ‘row ‘Number == 2’ < maillist | listtosh’
|
||
transforms the mailing list into the following format:
|
||
|
||
Number='2’
|
||
|
||
Name='Chiquita Banana’
|
||
Company=’United Brands’
|
||
|
||
Street=’Uno Avenito De La Revolution’
|
||
City='San Jose’
|
||
|
||
State='Costa Rica’
|
||
|
||
ZIP='123456789"
|
||
|
||
Phone=‘ 1234’
|
||
|
||
Once this is done, test the transformation by typing:
|
||
echo "$Name’s phone number is $Phone."
|
||
|
||
This writes the following on the standard output:
|
||
Chiquita Banana’s phone number is 1234,
|
||
|
||
See Also
|
||
tabletolist
|
||
|
||
listtotable — /rdb Command
|
||
|
||
Convert from list to table format
|
||
listtotable [ -el ] < listfile
|
||
|
||
listtotable converts a file in list format to table format. Some /rdb programs must see files
|
||
|
||
in table format, so the conversion is necessary.
|
||
|
||
In addition, table-formatted files are processed faster than list-formatted files. Any time you
|
||
send a list-formatted file through a pipe of two or more programs, even if they can handle
|
||
list format, convert them to table format so that the programs in the pipe will run two or
|
||
|
||
three times faster on average.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 251 / Buchseite 241 ====
|
||
listtotable 241
|
||
|
||
The reason that table-formatted files run so much faster is that a list file is often two or
|
||
three times larger than a table because of the repeated column names. Therefore, when
|
||
handling list-formatted files. the programs have to process two or three times as many
|
||
characters.
|
||
|
||
Options
|
||
listtotable recognizes the following options:
|
||
|
||
-e Expand each column to next tab stop. Ordinarily, table columns heads are only as
|
||
wide as list column heads.
|
||
|
||
-1_No head line in the list file. This option makes it possible to convert and sometimes
|
||
use the older list-formatted files.
|
||
|
||
Earlier versions of /rdb did not require the leading newline in the list-formatted file;
|
||
however, this requirement was added by later editions of /rdb to make it easy for its
|
||
commands to distinguish a list file from a table.
|
||
|
||
List and Table-Format Rules
|
||
List format looks like this:
|
||
|
||
Number 1
|
||
|
||
Name Ronald McDonald
|
||
Company McDonald’s
|
||
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
|
||
|
||
Remember there are three rules for constructing a list-format file:
|
||
|
||
1. The first character in the file is a newline. Be sure that there are no unseen spaces,
|
||
tabs, or nonprinting characters on the first line, or things will get quite messed up.
|
||
|
||
2. Each line consists of two columns separated by a tab. The first column is gives the
|
||
column's name, and the second column gives its values.
|
||
|
||
3. A newline character follows each row (record).
|
||
And there are three rules for contructing a table, as follows:
|
||
1. One tab between each column in a row. and a newline at the end.
|
||
|
||
2. Name ofthe column at the top of the column, in the first line of the file.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 252 / Buchseite 242 ====
|
||
242
|
||
|
||
lock
|
||
|
||
3. Adash line as the second line in the file.
|
||
|
||
Example
|
||
The command
|
||
|
||
listtotable < maillist
|
||
converts list file maillist into table format. The result appears as follows:
|
||
Number Name Company Street City State ZIP
|
||
|
||
1 Ronald McDonald McDonald’s 123 Mac Attack Memphis
|
||
TENN 30000 (111) 222-3333
|
||
|
||
2 Chiquita Banana United Brands Uno Avenito De La
|
||
Revolution San Jose Costa Rica 123456789 1234
|
||
|
||
When you look at this messy table, you can see the need for list format. The information in
|
||
each column is often too wide for the screen and wraps around to the next line.
|
||
|
||
See Also
|
||
tabletolist
|
||
|
||
Notes
|
||
If you use this command with a table instead of a list file, you will see a mess.
|
||
|
||
lock — /rdb Command
|
||
|
||
Lock a record or field of a file
|
||
lock filename processid from to indexfrom indexto
|
||
|
||
The command lock locks filename by writing a row into the lock file / tmp/Lfllename, which
|
||
contains one line for each locked record or field. Its command line contains the following
|
||
arguments:
|
||
|
||
processid
|
||
The process identifier of the program that locks filename.
|
||
|
||
JSrom The beginning point of the bytes to be locked.
|
||
to The end point of the bytes to be locked.
|
||
|
||
indexbegin
|
||
The beginning point of the index entry for the data being locked.
|
||
|
||
indexend
|
||
The end point of the index entry for the data being locked.
|
||
|
||
When a process attempts to lock a string of bytes that is already locked, lock returns an
|
||
error condition. You can test for this by using the COHERENT command test to test the
|
||
shell variable $?.
|
||
|
||
Example
|
||
|
||
Let's use lock on table inventory, which appears as follows:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 253 / Buchseite 243 ====
|
||
lowercase 243
|
||
|
||
Item Amount Cost Value Description
|
||
|
||
st 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
|
||
3 5 80 400 clamps
|
||
|
||
4 23 19 437 plates
|
||
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
H 5 5 175 875 scales
|
||
|
||
First. use seek to locate the record and return the offset and size, as follows:
|
||
|
||
LOCATION=‘echo 5 | seek -mb inventory Item‘
|
||
echo $LOCATION
|
||
207 245 0 8
|
||
|
||
This means that the record is offset 207 bytes into file inventory, and that it is 38 bytes
|
||
long, ending at byte 245. The O and 8 mean that there is no secondary index file.
|
||
|
||
Now we can call lock to lock the record:
|
||
lock inventory $$ $LOCATION
|
||
|
||
Note that we use the shell variable SLOCATION to supply the arguments from and to. We
|
||
also use the built-in shell variable $$ to write the process identifier on the command line.
|
||
|
||
The lock /tmp/Linventory has the following contents:
|
||
207 245 0 8
|
||
|
||
See Also
|
||
|
||
seek, unlock
|
||
COHERENT Lexicon: test
|
||
|
||
lowercase — /rdb Command
|
||
Transform text to lower case
|
||
lowercase [string ...] [< file]
|
||
|
||
The command lowercase converts to lower case every letter in string or file. If there are no
|
||
arguments, it reads and converts the standard input. It uses tr, the COHERENT character-
|
||
translation command, to do the converting.
|
||
|
||
Example
|
||
|
||
The command:
|
||
lowercase BIG WORDS
|
||
|
||
prints
|
||
big words
|
||
|
||
on the standard output.
|
||
|
||
If the file CAPITALS contains the string
|
||
THESE ARE ALL CAPS.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 254 / Buchseite 244 ====
|
||
244 ~ lowercase
|
||
|
||
then the command
|
||
lowercase < CAPITALS
|
||
prints on the standard output:
|
||
these are all caps.
|
||
|
||
See Also
|
||
|
||
cap, uppercase
|
||
COHERENT Lexicon: tr
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 255 / Buchseite 245 ====
|
||
maximum — menu 245
|
||
|
||
maximum — /rdb Command
|
||
Display the maximum value in a column
|
||
maximum [-1] [column...] < table
|
||
|
||
The command maximum displays the maximum value of each column. If no column appears
|
||
on the command line, maximum returns the maximum value in every column in table.
|
||
|
||
The -1 option writes the table to the standard output, as well as the minimum value for each
|
||
named column.
|
||
Example
|
||
|
||
For an example of this command, see the entry for total.
|
||
|
||
See Also
|
||
mean, minimum
|
||
|
||
mean — /rdb Command
|
||
Display the mean of a column
|
||
mean [-l1] [ column... ] < table
|
||
|
||
mean displays the mean value of each column. If no column appears on the command line,
|
||
mean returns the mean value for each column in table.
|
||
|
||
mean assign the value of zero to a blank line. This changes the value of the mean. If that
|
||
is not what you want, use the command rmblanks or compress -b to remove blank lines.
|
||
mean also treats blank values as zero
|
||
|
||
The option -1 prints the contents of the table, as well as the mean value for each named
|
||
column.
|
||
|
||
Example
|
||
|
||
For an example of this command, see the entry for total.
|
||
|
||
See Also
|
||
|
||
maximum, minimum
|
||
|
||
menu — /rdb Command
|
||
Root menu with some COHERENT commands
|
||
menu
|
||
|
||
The command menu displays a table of commands that you can execute by simply typing a
|
||
number or a name. Menus are useful for inexperienced users. Experienced users can set
|
||
up a menu very easily.
|
||
|
||
menu is a shell script that simply echos the menu table of choices, then waits for the user
|
||
to type a number or name. Then menu uses a shell case statement to execute a command
|
||
or series of commands for each choice. To set up your own menus, simply copy the menu
|
||
shell command from the $RDB/bin into your directory, then edit it. You should change its
|
||
name to Menu or Menu.something, to keep from confusing /rdb.
|
||
|
||
There is a sample local menu, named Menu in directory SRDB/demo.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 256 / Buchseite 246 ====
|
||
246 menu
|
||
|
||
Example
|
||
The following gives an example menu:
|
||
COHERENT MENU
|
||
Number Name For
|
||
0 exit leave menu or return to higher menu
|
||
1 Menu goto another local menu (if any)
|
||
2 sh get COHERENT shell
|
||
3 vi edit a file
|
||
4 mail read mail
|
||
5 send send mail to someone
|
||
6 cal see your calendar
|
||
7 who see who is on the system
|
||
8 1s list the files in this directory
|
||
9 cat display a file on the screen
|
||
10 rdb display rdb commands
|
||
Enter a number or name for the action you wish or DEL to exit:
|
||
|
||
menu waits for you to type your choice of number or name. Numbers are quicker to type.
|
||
but names are more easily remembered. and help you learn how to do things at the shell
|
||
level.
|
||
|
||
Setting Up Your Own Menus
|
||
|
||
You can automate your operations with menus. If you have naive users who might have
|
||
trouble learning or remembering the COHERENT or /rdb commands, you can set up menus
|
||
for them. Also, when you have an operation in which a few commands are repeatedly
|
||
executed, you can put them into a menu for simple choice.
|
||
|
||
You can put your menus in the directories in which they will be used or in your
|
||
SHOME/bin or other bin directory.
|
||
|
||
To start, go to the directory of your choice and copy the $RDB menu to your directory:
|
||
cp $RDB/bin/menu Menu
|
||
|
||
or
|
||
cp $RDB/demo/Menu .
|
||
|
||
We suggest the convention of using the name Menu with the capital ‘M' so it appears at the
|
||
top of your list of files when you do an le command.
|
||
|
||
You can then name submenus; for example, Menu.other where other is something that
|
||
suggests the kinds of commands the menu displays.
|
||
|
||
Now edit the Menu file. As you study the code, you will find that it is very easy to create
|
||
your own directory.
|
||
|
||
Menu is in two parts. The first part is the menu table:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 257 / Buchseite 247 ====
|
||
menu 247
|
||
|
||
cat << SCREEN
|
||
|
||
$CLEAR
|
||
Number Name
|
||
|
||
CWOMNINAU SP WNHHO
|
||
a
|
||
®
|
||
3
|
||
a
|
||
|
||
”
|
||
|
||
COHERENT MENU
|
||
|
||
leave menu or return to higher menu
|
||
goto another local menu (if any)
|
||
get unix shell
|
||
|
||
edit a file
|
||
|
||
read mail
|
||
|
||
send mail to someone
|
||
|
||
see your calendar
|
||
|
||
see who is on the system
|
||
|
||
list the files in this directory
|
||
display a file on the screen
|
||
display rdb commands
|
||
|
||
Please enter a number or name for the action you wish or DEL to exit:
|
||
|
||
SCREEN
|
||
|
||
The command cat simply sends to the screen everything after the command and before the
|
||
line that begins with SCREEN, including the line that begins Please enter a number.
|
||
|
||
The shell replaces $CLEAR on the first line with a sequence of characters that clears the
|
||
terminal. $CLEAR must have been set by the following command in the menu or in the
|
||
«profile file of the user:
|
||
|
||
CLEAR=‘clear’
|
||
|
||
The second part of Menu is a large case statement that you can edit to do what you want.
|
||
|
||
Here is a sample:
|
||
|
||
read ANSWER COMMENT
|
||
|
||
case $ANSWER in
|
||
|
||
O|exit)
|
||
1|Menu)
|
||
2|sh)
|
||
3|vi)
|
||
|
||
4|mail)
|
||
5| send)
|
||
|
||
exit 0 ;;
|
||
Menu ;;
|
||
sh 7;
|
||
|
||
echo ‘Which file or files do you wish to edit’
|
||
read ANSWER COMMENT
|
||
|
||
vi $ANSWER $COMMENT
|
||
|
||
rr
|
||
|
||
mail ;;
|
||
|
||
echo ‘Please enter login name of person to send mail to’
|
||
read ANSWER COMMENT
|
||
|
||
echo ‘Type you letter, and end by typing Ctrl-d’
|
||
|
||
mail $ANSWER
|
||
|
||
vi
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 258 / Buchseite 248 ====
|
||
248 minimum
|
||
|
||
6|cal) (cd ; calendar) ;;
|
||
?
|
||
|
||
7|who) who ;;
|
||
8|1ls) ls 3;
|
||
9|cat)
|
||
|
||
echo ‘Please enter the name of the file you wish to see’
|
||
read ANSWER COMMENT
|
||
cat $ANSWER
|
||
vi
|
||
10|rdb) menu.rdb ;;
|
||
*) echo ‘Sorry, but that number or name is not recognized.’ ;;
|
||
esac
|
||
|
||
The command read waits for the user to enter his choice. The first word typed is assigned
|
||
to the shell variable ANSWER. If the user types any more words, they are assigned to
|
||
variable COMMENT, which might be used in your commands.
|
||
|
||
Next is the case statement that examines SANSWER to decide which command to execute.
|
||
Note that the number and name are separated by a vertical-bar character ‘|’ to mean or:
|
||
Olexit) exit 0 ;;
|
||
|
||
This line is selected if type either 0 or exit. The command exit is then executed. The double
|
||
semicolons “;;" are required to show the end of the commands for this case statement.
|
||
|
||
Each case statement can hold any command or series of commands that you could type at
|
||
your terminal. esac at the bottom is case spelled backwards; it marks the end of the whole
|
||
case statement.
|
||
|
||
The expression *) catches any pattern that does not match earlier patterns. In this case, a
|
||
message is displayed. The pound sign ‘#' marks the beginning of a comment.
|
||
|
||
You have great power to do things as a result of the user selecting a choice. Of course, you
|
||
need to match the name and number in your menu table with the patterns in the case
|
||
statement; it is easy to edit the first part and forget to edit the second.
|
||
|
||
See Also
|
||
COHERENT Lexicon: case, cat, clear, echo, esac, ksh, read, sh
|
||
|
||
minimum — /rdb Command
|
||
Display the minimum of each column selected
|
||
minimum [ -1] [column...] < table
|
||
|
||
The command minimum returns the lowest value of each column in table. If no column is
|
||
named on the command line, minimum returns the minimum value for every column in
|
||
table. Blank lines are given the value of zero.
|
||
|
||
Option -I returns the contents of table, as well as the minimum value of each column.
|
||
|
||
Example
|
||
|
||
For an example of using the command in a script, see the total
|
||
|
||
See Also
|
||
maximum, mean, total
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 259 / Buchseite 249 ====
|
||
not — number 249
|
||
|
||
not — /rdb Command
|
||
Logical not, to reverse return status of command
|
||
not command ...
|
||
|
||
The command not converts a return status of zero to 255, and any nonzero return status to
|
||
zero. Thus, true becomes false and vice versa. This is used to test a command for not true
|
||
or false.
|
||
|
||
Example
|
||
|
||
This example shows how not reverses the return code of the COHERENT command true:
|
||
true ; echo $?
|
||
|
||
This command returns zero. On the other hand, the command
|
||
|
||
not true ; echo $?
|
||
|
||
returns 255.
|
||
|
||
See Also
|
||
COHERENT Lexicon: false, true
|
||
|
||
number — /rdb Command
|
||
Insert a column-row number into a table or list
|
||
Number < tableorlist
|
||
|
||
The command number creates appends a new column to the beginning of a table, or as the
|
||
first field in a list. The newly created column contains the number of each row in the table.
|
||
Unlike the related command Number, number writes the word “number” in lower-case
|
||
letters as the header on the column.
|
||
|
||
Example
|
||
For example. consider the following table, called inventory:
|
||
|
||
Item# Amount Cost Value Description
|
||
a: 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
|
||
|
||
Typing the command
|
||
number < inventory
|
||
|
||
yields the following result:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 260 / Buchseite 250 ====
|
||
250 Number
|
||
|
||
number Item# Amount Cost Value Description
|
||
1 1 3 5.00 15.00 rubber gloves
|
||
2 2 100 0.50 50.00 test tubes
|
||
3 3 5 8.00 40.00 clamps
|
||
4 4 23 1.98 45.54 plates
|
||
5 5 99 2.45 242.55 cleaning cloth
|
||
6 6 89 14.75 1312.75 bunsen burners
|
||
7 rf 5 175.00 875.00 scales
|
||
|
||
Note that the first column is the new number column.
|
||
|
||
See Also
|
||
Number, addcol, column, jointable, rename
|
||
|
||
Notes
|
||
|
||
To change the name of a column, use the command rename. To move the row-number
|
||
column to a different position within its table, use the command column. If you want to
|
||
change the name of the number column to something else, use the command rename.
|
||
|
||
Number — /rdb Command
|
||
|
||
Insert a column-row number into a table or list
|
||
Number < tableorlist
|
||
|
||
Number creates appends a new column to the beginning of a table, or as the first field in a
|
||
list. The newly created column contains the number of each row in the table. Unlike the
|
||
related command number, Number capitalizes the column heading — that is, the name of
|
||
the command sets the name of the column.
|
||
|
||
See Also
|
||
number
|
||
|
||
Notes
|
||
|
||
To change the name of a column, use the command rename. To move the row-number
|
||
column to a different position within its table, use the command column. If you want to
|
||
change the name of the number column to something else, use the command rename.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 261 / Buchseite 251 ====
|
||
pad 251
|
||
|
||
pad — /rdb Command
|
||
Add extra spaces at end of last column
|
||
pad [-number] < tableorlist
|
||
|
||
The command pad adds extra spaces to the end of the last column of each record in
|
||
tableorlist. number gives the number of spaces to add to the last column. The default is 70.
|
||
|
||
pad is useful for preparing up a file for updating by the command update. update writes an
|
||
edited record back into the file in the same place it was taken out. If you add characters
|
||
while editing the record, it will not fit.
|
||
|
||
The command replace looks for trailing and leading spaces to trim, to fit the record back. If
|
||
it does not find enough room, it appends the record to the end of the file. Padding gives
|
||
each record a fixed number of extra spaces to be trimmed as needed.
|
||
|
||
The traditional solution is to use fixed-length records and fields. To do this, you can use
|
||
the command justify to pad the file; but this often increase the file by two or three times.
|
||
That makes the file much larger, and increases the time needed to process it. pad lets you
|
||
control how much larger each record will be.
|
||
|
||
Example
|
||
To pad file maillist, type:
|
||
|
||
pad < maillist > tmp
|
||
|
||
To see the results, pipe the results to the command see:
|
||
pad < maillist | see
|
||
|
||
The following appears on the standard output:
|
||
|
||
Number *J1$
|
||
|
||
Name*JRonald McDonald$
|
||
|
||
Company*JMcDonald‘s$
|
||
|
||
Street*J123 Mac Attacks
|
||
|
||
City*JMenphis$
|
||
|
||
State*JTENNS
|
||
|
||
ZIP*J30000$
|
||
|
||
Phone*J(111) 222-3333 $
|
||
$
|
||
|
||
Number *J2$
|
||
|
||
Name*JChachita Banana$
|
||
|
||
Company*JUnited Brands$
|
||
|
||
Street*JUno Avenito De La Revolution$
|
||
|
||
City*JSan Jose$
|
||
|
||
State*JEl Salvadore$
|
||
|
||
ZIP*J123456789$
|
||
|
||
Phone*J1234 $
|
||
$
|
||
|
||
Note the dollar signs, which mark the end of the line, are far to the right of the last column,
|
||
Phone. Those are the 70 extra spaces that have been added; 70 being the default number of
|
||
spaces. On such a small record, that is probably far too many.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 262 / Buchseite 252 ====
|
||
252
|
||
|
||
padstring
|
||
|
||
Technical
|
||
|
||
Note that column Phone already had a value in it. If a value is already in the last column,
|
||
pad overwrites the spaces. If the value is longer than the number of spaces, pad writes the
|
||
value but adds no spaces.
|
||
|
||
We recommend that you have a last column named Comment or Remarks to act as a catch-
|
||
all for both comments and padding.
|
||
|
||
See Also
|
||
justify, replace, see, update
|
||
|
||
padstring — /rdb Command
|
||
|
||
Return string with blanks to fill a field
|
||
padstring [-Jlength string
|
||
|
||
The command padstring adds blanks to the end of string to make it the requested length.
|
||
This command useful for screen and report writing, where you want to line up everything.
|
||
|
||
The option -length means to left-justify the string in the field, that is, write the padding
|
||
blanks to the end of string. The option length, without the hyphen, right justifies the string
|
||
— that is, it adds the spaces to the beginning of string.
|
||
|
||
Example
|
||
The first example
|
||
padstring 10 string
|
||
displays the string:
|
||
string
|
||
Note that the string is right-justified; that is, the spaces were added to the left of string.
|
||
|
||
Now we can use this in a report form file to make fixed-length fields. An ordinary form has
|
||
the files to the right of a field, moving all around. For example, the command
|
||
|
||
report form < mailtable
|
||
|
||
writes the output:
|
||
|
||
Name : Ronald McDonald Company: McDonald’‘s
|
||
|
||
Street: 123 Mac Attack
|
||
|
||
City +: Menphis State : TENN ZIP: 30000
|
||
|
||
Phone : (111) 222-3333
|
||
|
||
Name +: Chiquita Banana Company: United Brands
|
||
|
||
Street: Uno Avenito De La Revolution
|
||
|
||
City +: San Jose State : Costa Rica ZIP: 123456789
|
||
|
||
Phone : 1234
|
||
|
||
This result is rather messy. However, if we edit the file form to include the padstring
|
||
command, then we will get a fixed form. as follows:
|
||
|
||
Name : <!padstring -17 ‘<Name>’!> Company: <Company>
|
||
Street: <Street>
|
||
City +: <!padstring -17 '<City>’!> State : <State> ZIP: <ZIP>
|
||
|
||
Phone : <Phone>
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 263 / Buchseite 253 ====
|
||
paste.rdb 253
|
||
|
||
Now, running report on this file yields:
|
||
|
||
Name : Ronald McDonald Company: McDonald’s
|
||
|
||
Street: 123 Mac Attack
|
||
|
||
City +: Menphis State +: TENN ZIP: 30000
|
||
Phone : (111) 222-3333
|
||
|
||
Name : Chiquita Banana Company: United Brands
|
||
|
||
Street: Uno Avenito De La Revolution
|
||
|
||
City +: San Jose State : Costa Rica ZIP: 123456789
|
||
Phone : 1234
|
||
|
||
Note that State has not been done yet, and therefore ZIP moves back and forth; but
|
||
Company and State stay lined up correctly.
|
||
|
||
Note that if padstring is too long a name, use the COHERENT link command In to link it to
|
||
a shorter name.
|
||
See Also
|
||
|
||
report, screen
|
||
COHERENT Lexicon: In
|
||
|
||
paste.rdb — /rdb Command
|
||
Paste together two or more tables
|
||
paste.rdb table! table2 ...
|
||
|
||
The command paste.rdb displays table1, table2, and so on, side by side. This is almost
|
||
identical to the COHERENT command paste.
|
||
|
||
The /rdb version of paste.rdb uses the COHERENT command pr to list the tables side by
|
||
side:
|
||
|
||
pr -m -t -s tablel table2 [...]
|
||
|
||
paste.rdb differs from the command jointable in that jointable looks for matching values
|
||
in key columns and writes only the rows in which it finds a match. paste.rdb does not care
|
||
what it is pasting together. You can get some interesting garbage with paste.rdb.
|
||
|
||
You can also do a kind of visual diff in which you can see an old and new file lined up side
|
||
by side. You could do this with two list files. but be careful, because the output will
|
||
generally not be acceptable by other /rdb programs.
|
||
|
||
Example
|
||
The following commands break the table inventory:
|
||
|
||
column Item Value < inventory > tmpl
|
||
column Cost Amount Description < inventory > tmp2
|
||
|
||
This yields table tmp1
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 264 / Buchseite 254 ====
|
||
254 ~—paste.rdb
|
||
|
||
Cost Amount Description
|
||
|
||
50 3. rubber gloves
|
||
5 100 test tubes
|
||
|
||
80 5 clamps
|
||
|
||
19 23 plates
|
||
|
||
24 99 cleaning cloth
|
||
|
||
147 89 bunsen burners
|
||
|
||
175 5 scales
|
||
|
||
Now, you can use paste.rdb to put them back together:
|
||
paste.rdb tmpl tmp2
|
||
This writes the following onto the standard output:
|
||
|
||
Item Value Cost Amount Description
|
||
|
||
1 150 50 3 rubber gloves
|
||
2 500 5 100 test tubes
|
||
|
||
3 400 80 5 clamps
|
||
|
||
4 437 19 23 plates
|
||
|
||
5 2376 24 99 cleaning cloth
|
||
6 13083 147 89 bunsen burners
|
||
7 875 175 5 scales
|
||
|
||
This is not an efficient way use column; one command could do the job, instead of two.
|
||
paste.rdb, however, it is a good way to put tables together if jointable is inappropriate. If
|
||
you had wanted to use jointable here, you should project column Item into both tables.
|
||
See Also
|
||
|
||
column, jointable
|
||
|
||
COHERENT Lexicon: diff, paste, pr
|
||
|
||
Notes
|
||
|
||
This command is named paste.rdb rather than paste, as in other implementations of /rdb,
|
||
to avoid clashing with the COHERENT command paste.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 265 / Buchseite 255 ====
|
||
path — precision 255
|
||
|
||
path — /rdb Command
|
||
Find the full path of a command
|
||
path [ command ... ]
|
||
|
||
The command path finds the directory path to a command, if it is in one of the directories
|
||
in your shell's PATH environment variable.
|
||
|
||
A path means two things in COHERENT:
|
||
|
||
1. It means the list of nested directories within which a file is located. For example. file
|
||
FOO may have the path of /usr/local/src/; this means that FOO is kept in directory
|
||
sre, which in turn is in directory local, which in turn is in directory usr, which in turn
|
||
is in directory /.
|
||
|
||
2. It means a list of directories that the shell searches to find an executable program that
|
||
matches the command typed in. Each user has his path stored in the environmental
|
||
variable PATH; to see your path, type the command:
|
||
|
||
echo $PATH
|
||
|
||
path searches the directories named in your PATH to find the path of command. If path
|
||
cannot find command or if command is not executable, it returns nothing.
|
||
|
||
Example
|
||
If you type:
|
||
path column
|
||
If this command returns
|
||
/usr/rdb/bin
|
||
then column lives in directory: /usr/rdb/bin.
|
||
|
||
Please note that for path to work, you must insert into your PATH the directory that holds
|
||
the /rdb commands.
|
||
|
||
See Also
|
||
|
||
COHERENT Lexicon: PATH, .profile
|
||
|
||
precision — /rdb Command
|
||
|
||
Display the precision of a column
|
||
precision [ -1] [column...] < table
|
||
|
||
The command precision returns the maximum number of digits to the right of the decimal
|
||
point in each column. If no column is named on the command line, precision returns
|
||
information on every numeric column in table.
|
||
|
||
The option -1 tells precision to return the entire table, in addition to the precision of each
|
||
column.
|
||
|
||
Example
|
||
For example of this command, see the entry for total.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 266 / Buchseite 256 ====
|
||
256 project — prompt
|
||
|
||
project — /rdb Command
|
||
|
||
Write selected projects (same as column)
|
||
project [ column... ] < tableorlist
|
||
|
||
The command project is another name for the command column.
|
||
|
||
See Also
|
||
column
|
||
|
||
prompt — /rdb Command
|
||
Echo a string on the standard output
|
||
prompt string ...
|
||
|
||
The command prompt echoes a string onto the standard output. It resembles the
|
||
COHERENT command echo, but it does not write a newline character after the echoed
|
||
string. Thus, you can use prompt to write a prompt onto the screen.
|
||
|
||
Example
|
||
|
||
The command
|
||
|
||
prompt "Please enter your name:
|
||
writes the following on the standard output:
|
||
Please enter your name: _
|
||
|
||
The underscore character marks where this command leaves the cursor.
|
||
|
||
See Also
|
||
|
||
chr
|
||
COHERENT Lexicon: echo
|
||
|
||
Notes
|
||
|
||
prompt looks for an environmental variable called ECHONOCR. If the variable is missing or
|
||
not equal to -n, then prompt calles the COHERENT command echo with its -n option.
|
||
which drops the newline. If ECHONOCR is set to anything other than -n, then prompt calls
|
||
\c option, which is used by some UNIX systems. When using /rdb under the COHERENT
|
||
system, it is best just to not set ECHONOCR.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 267 / Buchseite 257 ====
|
||
rdb — record 257
|
||
|
||
R
|
||
|
||
tdb — /rdb Command
|
||
|
||
List all /rdb programs in directory SRDB/bin
|
||
rdb
|
||
|
||
The command rdb prints on the standard output all commands in directory $RDB/bin.
|
||
This command is a shell script. which you should edit if its output is not to your liking.
|
||
|
||
See Also
|
||
act, helpme, whatis, whatwill
|
||
|
||
record — /rdb Command
|
||
Find and output a record from a table
|
||
record number < table
|
||
|
||
The command record searches through table for the record with the serial number number.
|
||
If it finds the record, it prints it and the table's header on the standard output.
|
||
|
||
Example
|
||
|
||
To retrieve the third record from table inventory, type:
|
||
record 3 < inventory
|
||
|
||
You will see something like the following:
|
||
|
||
Item Amount Cost Value Description
|
||
|
||
3 5 80 400 clamps
|
||
|
||
The following shell script uses record and read to find specific values in table inventory.
|
||
The command read uses the head line of inventory to assign values to each column name.
|
||
|
||
: describe - gives the description for an item in inventory
|
||
USAGE='usage: describe Item < table’
|
||
|
||
record $1 < inventory |
|
||
( read HEAD
|
||
read DASH
|
||
read $HEAD
|
||
echo "Item $Item is $Description"
|
||
)
|
||
When you type
|
||
|
||
describe 1 < inventory
|
||
you see output in the following format:
|
||
|
||
Item 1 is rubber gloves
|
||
|
||
See Also
|
||
|
||
row, search
|
||
COHERENT Lexicon: read
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 268 / Buchseite 258 ====
|
||
258 rename
|
||
|
||
rename — /rdb Command
|
||
Rename a column
|
||
|
||
rename [ oldcolumn newcolumn ... ] < tableorlist
|
||
|
||
The command rename changes the name of oldcolumn to newcolumn within tableorlist. You
|
||
can name on the command line as many oldcolumn/newcolumn pairs as you wish.
|
||
|
||
Example
|
||
|
||
Consider the table inventory:
|
||
|
||
Item# Amount Cost Value
|
||
1 3 5.00 15.00
|
||
2 100 0.50 50.00
|
||
3 5 8.00 40.00
|
||
4 23 1.98 45.54
|
||
5 99 2.45 242.55
|
||
6 89 14.75 1312.75
|
||
7 5 175.00 875.00
|
||
|
||
The command
|
||
|
||
Description
|
||
rubber gloves
|
||
test tubes
|
||
clamps
|
||
|
||
plates
|
||
cleaning cloth
|
||
bunsen burners
|
||
scales
|
||
|
||
rename Amount Qty Description Name < inventory
|
||
|
||
renames Amount to Qty. and Description to Name. The table now appears as follows:
|
||
|
||
Item# Qty Cost Value
|
||
1 3 5.00 15.00
|
||
2 100 0.50 50.00
|
||
3 5 8.00 40.00
|
||
4 23 1,98 45.54
|
||
5 $9 2.45 242.55
|
||
6 89 14.75 1312.75
|
||
7 5 175.00 875.00
|
||
|
||
If you have a list-formatted file, you
|
||
consider the list maillist:
|
||
|
||
Number 1
|
||
|
||
Name Ronald McDonald
|
||
Company McDonald’s
|
||
Street 123 Mac Attack
|
||
city Memphis
|
||
|
||
State TENN
|
||
|
||
ZIP 30000
|
||
|
||
Phone (111) 222-3333
|
||
|
||
LEXICON
|
||
|
||
Name
|
||
|
||
rubber gloves
|
||
test tubes
|
||
clamps
|
||
|
||
plates
|
||
cleaning cloth
|
||
bunsen burners
|
||
scales
|
||
|
||
can also rename the column names. For example.
|
||
|
||
==== PDF-Seite 269 / Buchseite 259 ====
|
||
replace 259
|
||
|
||
Number 2
|
||
|
||
Name Chiquita Banana
|
||
|
||
Company United Brands
|
||
|
||
Street Uno Avenido de la Reforma
|
||
city San Jose
|
||
|
||
State Costa Rica
|
||
|
||
ZIP 123456789
|
||
|
||
Phone 1234
|
||
|
||
The command
|
||
rename Number Num ZIP Zip < maillist
|
||
changes Number to Num, and ZIP to Zip. The list now appears as follows:
|
||
|
||
Num 1
|
||
|
||
Name Ronald McDonald
|
||
Company McDonald's
|
||
Street 123 Mac Attack
|
||
city Memphis
|
||
|
||
State TENN
|
||
|
||
Zip 30000
|
||
|
||
Phone (111) 222-3333
|
||
|
||
Num 2
|
||
|
||
Name Chiquita Banana
|
||
|
||
Company United Brands
|
||
|
||
Street Uno Avenido de la Reforma
|
||
|
||
city San Jose
|
||
State Costa Rica
|
||
Zip 123456789
|
||
Phone 1234
|
||
|
||
See Also
|
||
|
||
column
|
||
|
||
replace — /rdb Command
|
||
Insert a record into a file at specified location
|
||
replace [-a] [-m[bhirs] tableorlist from to [xfrom xto] < intableorlist
|
||
|
||
The command replace replaces the row at offsets from through fo in tableorlist with the
|
||
contents of intableorlist. replace will not insert a record larger than fo minus from. It adds
|
||
spaces to the last column of records within tableorlist that are smaller than the input
|
||
record.
|
||
|
||
xfrom and xto give the beginning and end of the offsets of the index entry within tableorlist's
|
||
associated fast-access table, should there be one.
|
||
|
||
To obtain painlessly the offsets of the record and its index entry, use the command seek.
|
||
This is demonstrated in the following example.
|
||
|
||
The command update remembers the location and size of the record it takes out of a file
|
||
and passes it to replace so that only a correctly sized file goes back into that file.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 270 / Buchseite 260 ====
|
||
260
|
||
|
||
replace
|
||
|
||
Options
|
||
|
||
replace recognizes the following options:
|
||
|
||
-a Do not append the record in intableorlist to the end of tableorlist. The default to
|
||
append if the record is too big to fit back into the location from which it was taken.
|
||
This option allows you to prevent appending. If you want a binary file to stay
|
||
sorted, you will either have to resort it or not allow appending.
|
||
|
||
-m{bhirs]
|
||
Fast access methods. See the manual page for index for a description of what each
|
||
of these options means.
|
||
|
||
Example
|
||
If table recordtable contains one record, you use can insert that record into table bigfile
|
||
with the following command:
|
||
|
||
replace bigfile 1421 1487 0 8 < recordtable
|
||
Note that the contents of recordtable replace rows 1421 through 1487 within bigfile.
|
||
For the second example, consider again table inventory, as follows:
|
||
|
||
Item Amount Cost Value Description
|
||
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
|
||
3 5 80 400 clamps
|
||
|
||
4 23 19 437 plates
|
||
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
First, let's use the command seek to extract a record, and save its offset in the shell variable
|
||
LOCATION:
|
||
|
||
LOCATION=‘echo 5 | seek -mr -o tmpfile inventory Item’
|
||
SLOCATION is initialized to the following
|
||
|
||
207 245 54 62
|
||
and tmpfile contains the following:
|
||
Item Amount Cost Value Description
|
||
|
||
S 99 24 2376 cleaning cloth
|
||
Here we use the record fast-access method.
|
||
Now let's change 99 to 199 within tmpfile. so we can see a change:
|
||
Item Amount Cost Value Description
|
||
|
||
5 199 24 2376 cleaning cloth
|
||
Now we can replace the edited record in inventory:
|
||
replace -mr inventory $LOCATION < tmpfile
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 271 / Buchseite 261 ====
|
||
report 261
|
||
|
||
inventory now appears as follows:
|
||
|
||
Item Amount Cost Value Description
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
3 5 80 400 clamps
|
||
4 23 19 437 plates
|
||
5 199 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
You can see that row 5 has been updated, because it now has 199 in it.
|
||
See Also
|
||
seek, update
|
||
|
||
report — /rdb Command
|
||
Write reports using a form and a table
|
||
report form < tableorlist
|
||
|
||
The command report produces reports, form letters, mailing labels, invoices, and so forth,
|
||
for each row in tableorlist, following the template within file form.
|
||
|
||
You must use a text editor to fill out form to determine how the form will appear. Insert
|
||
column names from tableorlist between angle brackets (< >) where you want the data to
|
||
appear within the report.
|
||
|
||
You can even call shell commands from within a form, pass them data from tableorlist, print
|
||
their output within your formatted form. This is a powerful extension to COHERENT shell
|
||
programming.
|
||
report mostly replaces the older commands label and letter. These commands are still part
|
||
of /rdb, in part for compatibility with older versions, and in part as examples of shell
|
||
programming.
|
||
|
||
Form Syntax
|
||
The following describes the format of a form:
|
||
|
||
regular text
|
||
form prints any characters in your form that do not match the symbols shown
|
||
below.
|
||
|
||
<column-name>
|
||
Angle brackets indicate that data from column-name in the current row of tableorlist
|
||
should be inserted in place of the column name.
|
||
|
||
<!command!>
|
||
Angle brackets and exclamation points indicate that the shell is to execute
|
||
command. Any output from command appears at this point in the report.
|
||
|
||
<!emd <col>!>
|
||
This is an insertion within a command. The data from column col in the current
|
||
row of tableorlist are passed to cmd. This passes the contents of col as an argument
|
||
to command. The output of command then replaces this entry within the form.
|
||
|
||
If report does not recognize a column name, it prints <column-name> as if it were normal
|
||
text. This allows you to use the angle brackets as literal characters within your form. if you
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 272 / Buchseite 262 ====
|
||
262 ~—srreport
|
||
|
||
wish. It also helps you debug your form: if the data from the table are not replacing
|
||
<column-name>, then column-name does not exactly match the column name in the table.
|
||
Check for spelling errors, upper- and lower-case discrepancies, embedded blanks, and
|
||
nonprinting characters.
|
||
|
||
Example
|
||
Consider table maillist, as follows:
|
||
|
||
Name Ronald McDonald
|
||
Company McDonald’s
|
||
Street 123 Mac Attack
|
||
city Memphis
|
||
|
||
State TENN
|
||
|
||
ZIP 30000
|
||
|
||
Phone (111) 222-3333
|
||
|
||
Name Chiquita Banana
|
||
|
||
Company United Brands
|
||
|
||
Street Uno Avenido de la Reforma
|
||
City San Jose
|
||
|
||
State Costa Rica
|
||
|
||
ZIP 123456789
|
||
|
||
Phone 1234
|
||
|
||
You could use an editor to develop a form like the following:
|
||
|
||
<Name>
|
||
|
||
<Company>
|
||
|
||
<Street>
|
||
|
||
< City >, <State> <ZIP>
|
||
|
||
Hi < Name >:
|
||
The date and time is <!date!>
|
||
We are also sending this letter to:
|
||
|
||
<! column Name City < mailtable | row ‘Name != "<Name>"’ | justify 1!>
|
||
Bye <! echo <Name> !>
|
||
|
||
Note that we have used all three types of inserts: column name, command, and command
|
||
insert. Now with these two files ready, you only need type
|
||
|
||
report form < maillist
|
||
|
||
to see the following output:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 273 / Buchseite 263 ====
|
||
reportwriter
|
||
|
||
263
|
||
|
||
Ronald McDonald
|
||
|
||
McDonald's
|
||
|
||
123 Mac Attack
|
||
|
||
Memphis, TENN 30000
|
||
|
||
Hi Ronald McDonald:
|
||
|
||
The date and time is Wed Aug 19 01:58:19 PST 1983
|
||
|
||
We are also sending this letter to:
|
||
|
||
Chiquita Banana San Jose
|
||
|
||
Bye Ronald McDonald
|
||
|
||
Chiquita Banana
|
||
|
||
United Brands
|
||
|
||
Uno Avenido de la Reforma
|
||
|
||
San Jose, Costa Rica 123456789
|
||
|
||
Hi Chiquita Banana:
|
||
The date and time is Wed Aug 19 01:58:40 PST 1983
|
||
|
||
We are also sending this letter to:
|
||
|
||
Ronald McDonald Memphis
|
||
|
||
Bye Chiquita Banana
|
||
|
||
<! echo -n ‘date’ I>
|
||
|
||
See Also
|
||
|
||
label, letter
|
||
COHERENT Lexicon: echo
|
||
|
||
reportwriter — /rdb Command
|
||
Sample program to write standard reports
|
||
reportwriter
|
||
|
||
Some users have noted that the shell escape places an extra line in the output. If you don't
|
||
want the extra line say something like:
|
||
|
||
The command reportwriter is a sample shell program that writes a sample standard report.
|
||
It uses the command splittable to divide a table into page-sized tables. It shows several
|
||
tricks for using COHERENT shell programming and /rdb tools to put together reports.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 274 / Buchseite 264 ====
|
||
264 ~—srmblank
|
||
|
||
Example
|
||
Here is what reportwriter produces (with the middle of each page replaced with an ellipsis
|
||
to keep the listing short):
|
||
|
||
Prices of Computers that ran UNIX(TM) in 1983
|
||
From Urban Software of New York City
|
||
Report Date: 9 Feb 1985
|
||
|
||
Price Company City
|
||
Advanced Micro Devices Santa Clara
|
||
Alcyon Corporation San Diego
|
||
American Telephone & Telegraph
|
||
BASIS Microcomputer GmbH D-4400 Muenster
|
||
Corvus Systems San Jose
|
||
David Computers Inc. Kitchener
|
||
Digital Computers Ltd. Tokyo 102
|
||
Heurikon Corp. Madison
|
||
|
||
Western Digital Irvine
|
||
Western Electric Corp.
|
||
|
||
4.2 Venturcom/IBM PC Cambridge
|
||
13.9 Victory Computer Systems, Inc. San Jose
|
||
Page 1
|
||
See Also
|
||
splittable
|
||
|
||
rmblank — /rdb Command
|
||
Remove blank rows from a table
|
||
rmblank < table
|
||
|
||
The command rmblank deletes from table all input rows that consist of only white space
|
||
(spaces and tabs). The related programs delete and replace blank out records. They can
|
||
be used in transaction processing where the files are too large to process and several users
|
||
are updating them. At a quiet time, the files can be compacted and reindexed.
|
||
|
||
Be sure to reindex any file that is processed by either rmblank or compress.
|
||
|
||
Example
|
||
|
||
First we have table inventory, as follows:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 275 / Buchseite 265 ====
|
||
rmblank 265
|
||
|
||
Item Amount Cost Value Description
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
3 5 80 400 clamps
|
||
4 23 19 437 plates
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
Then we delete record 4
|
||
|
||
echo 4 | delete inventory Item
|
||
|
||
and inventory now appears as follows:
|
||
|
||
Item Amount Cost Value Description
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
3 - 80 400 clamps
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
vf 5 175 875 scales
|
||
|
||
The command see shows the contents of inventory actually to be as follows:
|
||
|
||
Item*IAmount*ICost“IValue*IDescription $
|
||
----“[------ “I ---- “I -----* I-------------= $
|
||
1*z 3°I 50*I 150*Irubber gloves$
|
||
2°1 100° 5°I 500*Itest tubes$
|
||
3°I 5*I 80°I 400*Iclamps$
|
||
nf “I “I “I $
|
||
ax 99°I 24*I 2376*Icleaning cloth$
|
||
“Tt 89*I 147°113083*Ibunsen burners$
|
||
t: 5°I 175*I 875*Iscales$
|
||
|
||
yaw
|
||
|
||
A
|
||
|
||
Now the command
|
||
rmblank < inventory
|
||
|
||
removes lines that consist only of blanks. After we run this command, inventory appears
|
||
as follows:
|
||
|
||
Item Amount Cost Value Description
|
||
|
||
1 3 50 rubber gloves
|
||
2 100 5 test tubes
|
||
|
||
3 5 80 clamps
|
||
|
||
5 99 24 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 276 / Buchseite 266 ====
|
||
266 rmcore — row
|
||
|
||
Remember to reindex a file after you run rmblank on it.
|
||
|
||
See Also
|
||
compress, delete, index, replace, rmblank
|
||
|
||
rmcore — /rdb Command
|
||
Remove all core files
|
||
rmcore
|
||
|
||
The command rmcore uses the COHERENT system's command find to search for files
|
||
named core in the current directory and all subordinate directories. As its name implies, it
|
||
removes all such files that it finds.
|
||
|
||
Run this command first when you begin to fill up your disk. rmcore starts at the directory
|
||
you are in and goes down the file tree. If you are superuser, you can issue this command at
|
||
the root directory */'‘ and clean the whole system.
|
||
|
||
See Also
|
||
COHERENT Lexicon: core, find, rm
|
||
|
||
row — /rdb Command
|
||
Make a new table where rows match logical condition
|
||
row ‘column condition column-or-value ..* < table
|
||
|
||
The command row creates a new table from table. The new table consists of only those rows
|
||
that meet condition.
|
||
|
||
row uses a script written in the awk language. which gives you great power for specifying
|
||
the logical condition.
|
||
|
||
Several conditional expressions can be combined with the logical AND (&&) and OR (| |)
|
||
operators. Because the logical conditions are represented by special characters, they must
|
||
be enclosed by apostrophes, to protect them from being interpreted by the shell. If you have
|
||
special characters within a column name, enclose the column name in quotation marks.
|
||
|
||
Example
|
||
First a simple example. Consider table inventory
|
||
|
||
Item Onhand Cost Value Description
|
||
|
||
1 3 5 15 rubber gloves
|
||
2 100 1 100 test tubes
|
||
|
||
3 5 8 40 clamps
|
||
|
||
4 23 2 51 plates
|
||
|
||
5 99 2 97 cleaning cloth
|
||
6 89 18 1602 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
To make a table of all of the parts that cost more that $5. type:
|
||
row ‘Cost > 5’ < inventory
|
||
|
||
The new table appears as follows:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 277 / Buchseite 267 ====
|
||
row 267
|
||
|
||
Item Onhand Cost Value Description
|
||
|
||
3 5 8 40 clamps
|
||
|
||
6 89 18 1602 bunsen burners
|
||
7 , 5 175 875 scales
|
||
|
||
Now a more complex example. If you want a table of all the burners and of all of the items
|
||
of which we have fewer than ten in stock, type:
|
||
|
||
row ‘Description ~ /burner/ || Onhand < 10’ < inventory
|
||
|
||
The new table appears as follows:
|
||
|
||
Item Onhand Cost Value Description
|
||
|
||
1 3 5 15 rubber gloves
|
||
3 5 8 40 clamps
|
||
|
||
6 89 18 1602 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
The string ~ /burner/ searches for the string “burner” anywhere in the column. The double
|
||
pipe (| |) means logical OR.
|
||
|
||
Column Names
|
||
|
||
The commands row, compute, and validate recognize column names as upper- and lower-
|
||
case letters, digits, and the underscore ‘_'. The regular expression is [A-Za-z0-9_]. If you
|
||
have any other characters in your column names, put apostrophes or quotation marks
|
||
around them.
|
||
|
||
row compares the recognized strings with the table’s head line. Only if it finds a match
|
||
does it convert the string to the $1, $2... column positions that awk needs.
|
||
|
||
awk’s Reserved Words
|
||
|
||
awk is the pattern-scanning language that does all of the work for the commands row,
|
||
compute, and validate.
|
||
|
||
awk recognizes the following words as having special significance. If you name a columns
|
||
with any of these reserved words and then try to use them in a query, the /rdb commands
|
||
that are built around awk turn them into column positions and awk does not see them. It
|
||
is best to avoid these names as column heads or simply capitalize the first letter of each of
|
||
your column names.
|
||
|
||
This list also indicates the many functions you have with awk. However. do not rely on the
|
||
following descriptions. The tutorial section of your COHERENT manual contains a
|
||
summary of the awk language.
|
||
|
||
Please note that this list of awk functions and reserved words comes from UNIX System V.
|
||
Other implementations of awk may not contain all of these functions.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 278 / Buchseite 268 ====
|
||
268 row
|
||
Reserved Word Description
|
||
BEGIN.... -Pattern that matches before first input record
|
||
END .... .. Pattern that matches after last input record
|
||
break .. ..Exit the nearest for or while loop
|
||
continue... ...Go to next iteration of for or while loop
|
||
|
||
else.. Used in if then else expression
|
||
|
||
.. Leave program entirely, as if at end of input
|
||
|
||
.. Raise number to a power
|
||
|
||
..for (expression ; condition; expression)
|
||
|
||
..Get next input line
|
||
|
||
..df (condition) statement [else statement]
|
||
|
||
..for (variable in array) statement
|
||
|
||
.-dndex ( string1, string2 )
|
||
|
||
..Truncate argument to integer
|
||
|
||
-.Return current line length, or length of argument
|
||
.- Return log (to base 2) of argument
|
||
|
||
.. Skip to next record and reexecute all commands
|
||
. Output variables
|
||
|
||
.-printf ("format", variable, ... )
|
||
|
||
.- Split (string, arrayname, separator)
|
||
|
||
.. Sprintf ("format", variable, ... )
|
||
|
||
.. Return square root of argument
|
||
|
||
substr ( string, start, number )
|
||
|
||
. while ( condition ) statement
|
||
|
||
Although row is built around the awk language. row has the advantage of knowing about
|
||
the names of the columns. Therefore, you can use column names instead of column
|
||
positional numbers. To grasp the full power of row and compute. read the COHERENT
|
||
manual's tutorial on awk.
|
||
|
||
See Also
|
||
|
||
compute, row, select, validate
|
||
COHERENT Tutorials: Introduction to the awk Language
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 279 / Buchseite 269 ====
|
||
sale 269
|
||
|
||
Ss
|
||
|
||
sale — /act/sales Command
|
||
Enter sale order, and item, update customer
|
||
sale
|
||
|
||
The command sale is part of the accounting/sales system included with /rdb. It enters a
|
||
sales order into table saleorder and items into table saleitem. It also permits an order-taker
|
||
to add a new customer to the customer-information table customer, or to update
|
||
information on an existing customer.
|
||
|
||
Example
|
||
|
||
sale is interactive, to allow you to confirm each action. First, it asks for customer number.
|
||
If you give it a number, it looks the number up in table customer. If it finds a customer
|
||
with that number, it displays information on that customer for you to confirm. If you do
|
||
not have the customer's number, you can search with the slash string option or enter the
|
||
question mark to enter customer. There, you can search for the customer or add a new
|
||
customer.
|
||
|
||
The following gives an example order-entry session:
|
||
|
||
MakeaPile, Inc. saleorder
|
||
|
||
Enter Customer Number (? for new, /string search, Return to exit) 1
|
||
Vendor Number 1
|
||
|
||
Mr. Luke Skywalker CEO
|
||
|
||
Rebel Enterprises
|
||
123 Lea Street
|
||
Space Port City, Far Side 123456789 Tatooy
|
||
|
||
rdb 1
|
||
|
||
Order Number Code Backord Qty Price Total Name
|
||
1 1 rdb 10 1 1500 1500.00 /rdb
|
||
Number Cust Date Shipped Gross Tax Total
|
||
|
||
Ft 2 850723 0 1500.00 75.00 1575.00
|
||
|
||
Is this correct? (y, n) y
|
||
After you have confirmed the order, table sale modifies table salesorder, as follows:
|
||
|
||
Number Cust Date Shipped Gross Tax Total
|
||
|
||
1 2 850723 860525 1500.00 75.00 1575.00
|
||
|
||
2 2 850724 860525 3000.00 150.00 3150.00
|
||
|
||
3 3 850902 860525 22500.00 1125.00 23625.00
|
||
4 3 850902 0 36000.00 1800.00 37800.00
|
||
5 3 850902 0 21000.00 1050.00 22050.00
|
||
|
||
It also modifies table salesitem, as follows:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 280 / Buchseite 270 ====
|
||
270
|
||
|
||
schema
|
||
|
||
Order Number Code Backord Qty Price Total Name
|
||
|
||
1 L rdb 10 1 1500 1500.00 /rdb
|
||
2 1 rdb 10 2 1500 3000.00 /rdb
|
||
3 1 rdb 10 5 1500 7500.00 /rdb
|
||
3 2 act 10 10 1500 15000.00 /act
|
||
4 1 rdb 105 1500 7500.00 /rdb
|
||
4 2 rdb 10 19 1500 28500.00 /rdb
|
||
5 1 rdb 10 5 1500 7500.00 /rdb
|
||
5 2 act 10 9 1500 13500.00 /act
|
||
|
||
Once you enter the correct customer number, sale gives you a table of items to enter. Type
|
||
in Code and Qty, and the program looks up the other information in the inventory. Verify
|
||
that the information is correct and make sure that you have enough in inventory to satisfy
|
||
the order. Continue entering items until you are through. Pressing <Return> indicates
|
||
that you are finished; sale then calculates the totals for the order, including tax.
|
||
|
||
This program uses the commands cursor and termput to maneuver about the screen.
|
||
|
||
See Also
|
||
cursor, invoice, postar, termput
|
||
|
||
schema — /rdb Command
|
||
|
||
Print a table’s schema
|
||
schema tableorlist ...
|
||
|
||
The command schema prints the schema, or a data-base dictionary, for each tableorlist.
|
||
|
||
Other data-base systems require that you define a schema prior to creating a table. In
|
||
/rdb, you can derive a schema from an existing table or tables.
|
||
|
||
Example
|
||
|
||
The following command combines the schemas for tables inventory and maillist. The
|
||
example pipes the concatenated schema through the command justify to “pretty up” the
|
||
output:
|
||
|
||
schema inventory maillist | justify
|
||
|
||
This produces the following:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 281 / Buchseite 271 ====
|
||
screen 271
|
||
|
||
Table Field Name
|
||
inventory 1 Item
|
||
inventory 2 Amount
|
||
inventory 3 Cost
|
||
inventory 4 Value
|
||
inventory 5 Description
|
||
maillist x Number
|
||
maillist 2 Name
|
||
maillist 3 Company
|
||
maillist 4 Street
|
||
maillist 5 city
|
||
maillist 6 State
|
||
maillist ae ZIP
|
||
maillist 8 Phone
|
||
Because schema is a shell script. you can modify it to give widths of columns, data types,
|
||
and so on.
|
||
|
||
See Also
|
||
|
||
datatype, precision, width
|
||
|
||
screen — /rdb Command
|
||
Convert a form into a screen-input shell program
|
||
screen <form > shellprogram
|
||
|
||
The command screen reads form and writes a COHERENT shell program that paints the
|
||
screen and reads a user's input. Because the output of screen is a shell script. you can
|
||
edit it to validate data, read data and write it onto the screen, and so on. form must be in
|
||
the same format as described in the manual entry for the command report.
|
||
|
||
screen writes a simple shell script. The script works “as is" to read data typed onto the
|
||
screen and to write a standard table. It uses the /rdb command cursor to move to each
|
||
input field on the screen.
|
||
|
||
A script output by screen can be used in many ways. You can use it as a form, to enter
|
||
data into a new table. You can edit the script to have it append its output into an existing
|
||
table, to pass its data via a pipe to another command, or to read data from a table and
|
||
display them on the screen. Commands can be edited into the screen-form script. You can
|
||
add calls to the /rdb command validate, to confirm that the user has added data that are
|
||
at least sensible. You can even embed the script within another shell script, to perform
|
||
screen entry for it.
|
||
|
||
Setup Steps
|
||
|
||
To create a screen-entry form, do the following:
|
||
1. Use your text editor to write the screen-form file.
|
||
|
||
2. Run screen to read the form file. Redirect its output into the file in which you wish
|
||
to store the form’s executable script.
|
||
|
||
3. Edit the shell script to meet your requirements, such as adding validation, record
|
||
locking, and so forth.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 282 / Buchseite 272 ====
|
||
272
|
||
|
||
screen
|
||
|
||
4. Run the executable shell script to input data and write a new table.
|
||
|
||
Example
|
||
A simple form looks like this:
|
||
|
||
Mail List Entry Form
|
||
|
||
<Idatel>
|
||
Name : <Name> Company: <Company>
|
||
Street: <Street>
|
||
City : <City> State : <State> ZIP: <ZIP>
|
||
|
||
Phone : <Phone>
|
||
|
||
Everything is written to the screen except what is between angle brackets “<>", which are
|
||
variables to be input. Exclamation marks within angle brackets (e.g.. <!date!>) mark
|
||
commands to execute when the program is running.
|
||
|
||
When screen reads the above form and compiles it, it writes the following shell script:
|
||
|
||
: paint crt screen
|
||
|
||
exec 1>/dev/tty
|
||
|
||
cat <<SCREEN
|
||
|
||
$ {CLEAR} Mail List Entry Form
|
||
|
||
Name : Company:
|
||
|
||
Street:
|
||
|
||
City : State : ZIP:
|
||
Phone :
|
||
|
||
SCREEN
|
||
|
||
+ read user input
|
||
cursor 1 23 date;
|
||
|
||
;
|
||
|
||
cursor 3 8 ; read Name;
|
||
cursor 3 36 ; read Company;
|
||
cursor 4 8 ; read Street;
|
||
cursor 5 8 ; read City;
|
||
cursor 5 36 ; read State;
|
||
cursor 5 55 ; read ZIP;
|
||
cursor 6 8 ; read Phone;
|
||
|
||
t output table head
|
||
|
||
exec 1>&2
|
||
|
||
echo “Name Company Street City State ZIP Phone
|
||
echo “---- 9 ------- ------ eor- oo wee see "
|
||
: append row
|
||
|
||
echo "$Name $Company $Street $City $State $ZIP $Phone"
|
||
This shell progam is in three parts, each introduced by a comment:
|
||
|
||
paint crt screen
|
||
This section clears the screen, then paints the form onto it.
|
||
|
||
read user input
|
||
This section moves the cursor to each input field, then waits for the user to enter a
|
||
string of characters. Each field is linked to a column; that is, what the user types
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 283 / Buchseite 273 ====
|
||
search 273
|
||
|
||
in that field will be written into the column to which the field is linked.
|
||
|
||
output table head
|
||
The final section writes the new table in standard /rdb format: that is. a column
|
||
header followed by the row of data entered by the user.
|
||
|
||
To let you use the screen program in a pipe, the generated commands send the interactive
|
||
output to the screen through the standard output temporarily tied to /dev/tty, and to the
|
||
output table through the standard-error device. To accomodate COHERENT's
|
||
implementation of exec, you must tie the standard error to the standard output when you
|
||
run the script screen has created, For example
|
||
|
||
mail.s > mail.t 2>&1
|
||
The following shows the form compiled above, with example data:
|
||
|
||
Mail List Entry Form
|
||
Wed Sep 4 14:09:30 EDT 1987
|
||
|
||
Name : Hi Ho Company:
|
||
Street: 1st St.
|
||
City : LA State : CA ZIP: 90024
|
||
|
||
Phone : 213-555-1212
|
||
|
||
The above input creates the following table:
|
||
|
||
Name Company Street City State ZIP Phone
|
||
|
||
Hi Ho HH Inc. Ist St. LA CA 90024 213-555-1212
|
||
|
||
You can redirect output into a file or pipe. Here, it was directed into table mail.t. You can
|
||
use this table as its stands alone, or you can append it to another table by by piping it to
|
||
the append command. For example:
|
||
|
||
mail.s 2>&1 | append mail.t
|
||
|
||
See Also
|
||
|
||
cursor, lock, unlock, validate
|
||
COHERENT Lexicon: cat, echo, exec, ksh, read, sh
|
||
|
||
search — /rdb Command
|
||
|
||
Search a table
|
||
search [-m{bhirs]] [-hsnx +x] [-1 [2> location]] tableorlist [keycolumn ...] [ < keytable ]
|
||
|
||
The command search finds a row quickly. It searches tableorlist for each row in which the
|
||
value keycolumn matches one or keys you supply. The key or keys can either be entered
|
||
interactively, or read from keytable. You must use the /rdb command index to index
|
||
tableorlist before you can use search to search it.
|
||
|
||
By default, a key’s value must match exactly the string within keycolumn. The options -x
|
||
and +x modify this behavior; they are described below.
|
||
|
||
You can use search in any of several different ways. Because it reads the key values from
|
||
the standard input, you can input the keys by typing them interactively at the terminal, by
|
||
diverting the contents of keytable into it, or by piping the output of a command into it.
|
||
Each method is demonstrated in the examples given below. Therefore, it is easy to use
|
||
search on a command line or in a shell script. For example, the command domain is a
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 284 / Buchseite 274 ====
|
||
274
|
||
|
||
search
|
||
|
||
shell script that uses search to speed its searches. If you use a pipe to pass data to search,
|
||
think of a stream of keys going into it and a stream of matching rows coming out.
|
||
|
||
search can use a number of different methods of searching. There are advantages and
|
||
disadvantages to each; different sizes and structures of tables are best suited to different
|
||
methods of searching. If you are not sure which method to use, you can try them all on
|
||
your tableorlist. Use the COHERENT command time to find how long each method takes.
|
||
then pick the one that runs the fastest. Another /rdb command, timesearch, runs each
|
||
form of search on the sample unixtable, which is kept in directory $RDB/demo. Because
|
||
timesearch is a shell script. you can modify it to time the different methods for your own
|
||
file.
|
||
|
||
The behavior of search depends upon which method of searching you choose. With some
|
||
methods, it first searches another table (called the “secondary index file") built by the
|
||
command index. One method, sequential, searches every row in tableorlist.
|
||
|
||
If you change tableorlist, such as when you add a new row or delete an old one, you must
|
||
reindex it. If you develop application programs, you can have them update secondary index
|
||
files to handle dynamic file-processing.
|
||
|
||
Methods of Searching
|
||
|
||
The following describes the different methods of searching a table. Each method is
|
||
introduced by the command-line option with which you can invoke it:
|
||
|
||
-m Perform a sequential search. This is the default method.
|
||
|
||
-mb Binary search. This first looks at the middle record of the file. If the key column's
|
||
value is greater than that of the key that search is seeking, then search look at the
|
||
record one quarter of the way through the file. search continues to bifurcate the
|
||
table until it finds the row, or finds that the row is not there.
|
||
|
||
The method of searching requires that you first sort the table on the key column.
|
||
|
||
A binary search takes log(2)n accesses:
|
||
|
||
Accesses No. of Records
|
||
10 1 thousand
|
||
20 1 million
|
||
30 1 billion
|
||
40 1 trillion
|
||
|
||
Binary searching is a good method for searching tables that must remain sorted on
|
||
the key column.
|
||
|
||
-mh Hash searching. A hash search computes an address from the key and looks into a
|
||
secondary file at that address. If the key matches, it retrieves the address of the
|
||
row you want in the main file and then retrieves it. If the address search hashes to
|
||
is empty (i.e., has a value of zero), then the key does not match and the row is not
|
||
in the file.
|
||
|
||
Occasionally, another key is there that happens to hash to the same address; this is
|
||
called a collision. When a collision occurs, search will keep looking at subsequent
|
||
entries in the secondary table until it either finds a match or finds an empty or
|
||
deleted (-1) entry.
|
||
|
||
A hash search usually takes two disk accesses when the hash table is half full. For
|
||
this reason, /rdb sets up hash tables that are twice as large as the number of
|
||
records being hashed. As the data table grows, it must be reindexed to keep the
|
||
hash speed up.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 285 / Buchseite 275 ====
|
||
search 275
|
||
|
||
-mi
|
||
|
||
Hashing is a good method for tables that are static or change only rarely.
|
||
|
||
Inverted or indexed searching. An inverted search uses a secondary file that must
|
||
have been created by index. This index table has two columns: the key column
|
||
from the data table, sorted to allow binary searching; and the offset of each key-
|
||
column value within the data table. When search finds the key in the index table's
|
||
key column, it then uses value from the address column to retrieve the row from
|
||
the data table in a single disk read. The inverted method takes a little longer than
|
||
binary, but sorting the index file is much faster than sorting the data table.
|
||
|
||
Record number searching. A record search simply retrieves the row requested. For
|
||
example, if you enter ‘5’, you will get the fifth row in the data table.
|
||
|
||
To retrieve a record by its row number, search reads a secondary file that that
|
||
contains the offset for each record in the data table. The record method is a faster
|
||
way to retrieve a record; however, you must know the number of the record you
|
||
want, and you must either keep the data table in that order, or reindex it. You can
|
||
use the command replace to move a row to the of its table and update the
|
||
secondary index to point to the row's new location.
|
||
|
||
Sequential or linear searching. A sequential search examines all records in the data
|
||
table in the order in which they appear. It is not a fast-access method, although it
|
||
may still be faster than that used by the command row. It is provided as a
|
||
benchmark for timing other methods. If your ‘ile is not big enough to make the
|
||
other access methods worthwhile, just use sequential search or row and save
|
||
yourself the overhead of building and maintaining an index.
|
||
|
||
A sequential search can search multiple key columns, and and can search any
|
||
column. The sequential method is better than the COHERENT command grep
|
||
because it looks at one column, whereas grep scans the entire row for a pattern
|
||
match.
|
||
|
||
Other Options
|
||
|
||
search also recognizes the following command-line options:
|
||
|
||
-h
|
||
|
||
-l
|
||
|
||
+X
|
||
|
||
Do not print the table’s head line. By default, search prints the head line of the
|
||
table it searches as well as all rows it finds. The -h option suppresses the printing
|
||
of the head line and prints only the rows you are seeking.
|
||
|
||
Output the location of the record in the data table and the location of the index
|
||
record in the index table. These locations is in the form _fromtoxfromxto , and can
|
||
be piped to the commands replace, lock, and unlock. search writes these data to
|
||
the standard-error device. to separate them from the table it writes to the standard
|
||
output.
|
||
|
||
Because search is a shell program, it demonstrates how you can do this in your
|
||
own programs. Turning on this option also turns on the -s option because /rdb
|
||
allows you to lock or replace one record at a time. Therefore, all keys in your file
|
||
must be unique, or some will never be found.
|
||
|
||
Search for only one row. This speeds the search because search quits when it finds
|
||
the first match and continue searching the file.
|
||
|
||
Partial match and case insensitive, like the Berkeley command look.
|
||
|
||
Exact match, including blank characters. The default matching ignores blank
|
||
characters.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 286 / Buchseite 276 ====
|
||
276
|
||
|
||
search
|
||
|
||
Examples
|
||
Assume you have a file called inventory, which appears as follows:
|
||
|
||
Item Amount Cost Value Description
|
||
|
||
NOAUBRWNHE
|
||
|
||
3 50 150 rubber gloves
|
||
100 5 500 test tubes
|
||
5 80 400 clamps
|
||
23 19 437 plates
|
||
99 24 2376 cleaning cloth
|
||
89 147 13083 bunsen burners
|
||
5 175 875 scales
|
||
|
||
If you had indexed the column Description, then you have several ways to find rows:
|
||
|
||
1.
|
||
|
||
Interactively type key values. search immediately prints the rows it finds. For
|
||
example, type:
|
||
search -mh inventory Description
|
||
|
||
search responds with the head line of the inventory table. Now you can type names, in
|
||
this example scales; if search finds a match, it returns the row that contains the key.
|
||
|
||
Divert a table or list file to search. You can create a table with a column of key values;
|
||
for example:
|
||
|
||
Description
|
||
|
||
scales
|
||
clamps
|
||
|
||
The following command line diverts this table into search
|
||
search -mh inventory Description < description
|
||
and produces the following output:
|
||
|
||
Item Amount Cost Value Description
|
||
7 5 175 875 scales
|
||
3 5 80 400 clamps
|
||
|
||
Input keys through a COHERENT pipe. For example, the command
|
||
column Description < sometable | search -mh inventory | column Value
|
||
returns the following:
|
||
|
||
Value
|
||
|
||
If you wish to justify a table like this, just pipe the output of search to the command
|
||
justify.
|
||
This lets you use the COHERENT command echo to pipe a key value:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 287 / Buchseite 277 ====
|
||
searchtree 277
|
||
|
||
echo scales | search -mh inventory Description
|
||
which returns the following to the standard output:
|
||
|
||
Item Amount Cost Value Description
|
||
|
||
z 5 175 875 scales
|
||
|
||
In shell programming, you can capture the output of a program or a pipe by putting it
|
||
within two grave (‘) symbols. In a shell script, you can set an environmental variable like
|
||
this:
|
||
|
||
RECORD=‘echo key | search -mh -h bigtable column’
|
||
The command echo $RECORD displays the data diverted into this variable; for example:
|
||
7 5 175 875 scales
|
||
|
||
Now the RECORD environmental variable is equal to the matching row in the table. Note
|
||
the -h is important to keep the head line from being written into RECORD.
|
||
|
||
Search vs. Select
|
||
|
||
search is important for application programs written in shell scripts, the C programming
|
||
language, or other code. It can be used interactively, but the command row is much more
|
||
powerful because it can seek combinations of logical conditions, regular expressions, and
|
||
conditions such as greater than, whereas search needs a key (either exact or partial). But
|
||
for pulling a row out of a big table, search can speed things up enough to be preferred. In
|
||
summary, search is for high-speed access with keys, whereas row should be used to
|
||
retrieve rows that match complex logical conditions and regular expressions.
|
||
|
||
See Also
|
||
|
||
append, column, delete, index, replace, row, seek, update
|
||
COHERENT Lexicon: egrep, grep, look, time
|
||
|
||
searchtree — /rdb Command
|
||
Seek a string node in tree table
|
||
searchtree [-m[(bhirs]] table root goal column! column2
|
||
|
||
The command searchtree searches table to see if string root in column! is associated with
|
||
goal in column2. It returns TRUE to the shell if it find that root is associated with goal, or
|
||
FALSE if it is not.
|
||
|
||
goal may be within table, in which case the COHERENT command grep can also find it:
|
||
searchtree, however. will also see if goal be reached by a path from root.
|
||
|
||
The options -m[bhirs] name the fast-access method to use. The default is sequential (-ms).
|
||
See the entry for the command search for a full description of each method of searching.
|
||
|
||
searchtree is a breadth-first search that uses the search fast-access methods to find all of
|
||
the children at each level of a tree. This is the kind of search often done in artificial
|
||
intelligence programs. However, searchtree stores its data in a temporary file rather than
|
||
in memory, so that it will work on very large data bases.
|
||
|
||
Because searchtree is a shell script. you can modify it to serve many kinds of searches.
|
||
For example. you can add a message like yes/no or true/false. You can also add shell code
|
||
to print out a path. You might want to use heuristics to guide the search at each level, and
|
||
side effects to update data or print messages along the way.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 288 / Buchseite 278 ====
|
||
278
|
||
|
||
searchtree
|
||
|
||
This kind of searching is also used by the PROLOG language. searchtree, however, differs
|
||
from PROLOG in two significant respects. First, PROLOG must have its data base in
|
||
memory, which limits the size of the database it can handle. Second, PROLOG uses depth-
|
||
first searching, which requires it to backtrack.
|
||
|
||
Example
|
||
|
||
Consider the tree represented by table isa, as follows:
|
||
|
||
Name Isa
|
||
|
||
barbara human
|
||
|
||
bill human
|
||
evan human
|
||
rod human
|
||
|
||
human primate
|
||
primate mammal
|
||
|
||
cat mammal
|
||
dog mammal
|
||
mammal animal
|
||
bird animal
|
||
fish animal
|
||
|
||
animal lifeform
|
||
plant lifeform
|
||
|
||
Remember that all trees, in fact all graphs, can be listed as tables when the nodes (vertices)
|
||
that are connected by a line (arcs) that is on each row. A directional graph is handled by
|
||
having one column be From and another be To.
|
||
|
||
The following command uses searchtree to examine table isa to see if entity rod in column
|
||
Name is of type lifeform as given in column Isa:
|
||
|
||
searchtree isa rod lifeform Name Isa ; echo $?
|
||
|
||
The command echo $? prints the value returned by searchtree. In this case. you see ‘0’ (or
|
||
FALSE), because rod is not a lifeform; rather it (or he) is a human.
|
||
|
||
Because searchtree returns only a status code, you can use it as a test condition. Your
|
||
shell program could have a statement like this:
|
||
|
||
prompt “What is your name: "
|
||
read NAME
|
||
if searchtree isa $NAME lifeform Name Isa
|
||
then
|
||
echo “So, I am talking to a lifeform."
|
||
else
|
||
echo "So, I am talking to another machine."
|
||
fi
|
||
|
||
The following gives an sample exchange with this script; text in bold gives what the user
|
||
types:
|
||
|
||
What is your name: rod
|
||
|
||
So, I am talking to a lifeform.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 289 / Buchseite 279 ====
|
||
see 279
|
||
|
||
The result of the search of the tree was tested by the if statement, and used to decide which
|
||
message to print.
|
||
|
||
See Also
|
||
search
|
||
|
||
Notes
|
||
If you wish to experiment with PROLOG, volume 2 of COHware includes the source code to
|
||
a PROLOG interpreter.
|
||
|
||
see — /rdb Command
|
||
Display nonprinting as well as printing characters
|
||
see < tableorlist
|
||
|
||
The command see displays the contents of tableorlist. Unlike the COHERENT command cat,
|
||
see represents all nonprinting characters by converting them to the form “some-printing-
|
||
character. It is essentially the same as the Berkeley UNIX commands see or cat -v.
|
||
|
||
see is very useful for seeing if you have placed tabs into your tables or lists. Tabs print out
|
||
as “I because they are also obtained by typing <ctrl-I>. see is also helpful for finding
|
||
nonprinting characters.
|
||
|
||
Example
|
||
To see the if the tabs are placed correctly in table badtabie, type:
|
||
|
||
see < badtable
|
||
|
||
You'll see something like:
|
||
Date*IAccount *IDebit *ICredit *IDescription$
|
||
|
||
820102*1I101*1I25000*I*Icash from loan$
|
||
820102*I211.1*I*I25000*Iloan number #378-14 Bank Amerigold$
|
||
820103*T150.1 10000*I*Itest equipment from Zarkoff$
|
||
820103*°1101*I*1I5000*Icash payment$
|
||
820103*I211.2*I*1I5000*Inote payable to Zarkoff Equipment$
|
||
820104*I130*°I30000*I*Iinventory - parts from CCPSC$
|
||
820104*1I201.1*I*I15000*Iaccounts payable to CCPSC$
|
||
820104*T101*1*1I15000*Icash payment to CCPSC for parts$
|
||
|
||
See Also
|
||
COHERENT Lexicon: ASCII
|
||
|
||
Notes
|
||
|
||
see assumes ASCII characters with a value between O and 127. see adds 128 to negative
|
||
characters and to characters with values greater than 127. It then adds the value of ASCII
|
||
‘A’ to characters with a value less than that of a blank character (ASCII 32) so they map to
|
||
the upper-case characters. —
|
||
|
||
For example, NUL is printed as *@, a tab character as “I, and a form-feed character as *L.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 290 / Buchseite 280 ====
|
||
280
|
||
|
||
seek
|
||
|
||
seek — /rdb Command
|
||
|
||
Return the beginning and ending offset of a row
|
||
seek [-m[bihrs]] [-o out/lle} tableorlist [keycol...] < file
|
||
|
||
The command seek returns the offsets of the beginning and end of a record in tableorlist. It
|
||
uses the command search with its location option -l.
|
||
|
||
The offset and size integers returned can be used by the replace to write a new record.
|
||
They are also used by the commands lock and unlock to set and remove record locks.
|
||
|
||
Options
|
||
|
||
seek recognizes the following options:
|
||
|
||
-m{[bhirs]
|
||
Fast access methods. See the manual entry for the command search for a full
|
||
description of various search options and how you can invoke each.
|
||
|
||
-o Write the found record into outfile.
|
||
|
||
Example
|
||
Let's use seek on the table inventory, which is as follows:
|
||
|
||
Item Amount Cost Value Description
|
||
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
|
||
3 5 80 400 clamps
|
||
|
||
4 23 19 437 plates
|
||
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
The following command invokes seek to find row 5:
|
||
echo 5 | seek -mb inventory Item
|
||
|
||
This writes the following to the standard output:
|
||
207 245 0 8
|
||
|
||
This means that the record is 207 bytes into the file and that it is 38 bytes long, ending at
|
||
byte 245.
|
||
|
||
The next example extracts a row from inventory blanks it out. then writes the row back
|
||
into inventory on top of the original row. First, extract the row:
|
||
|
||
LOCATION=‘echo 5 | seek -mb -o tmp inventory Item’
|
||
|
||
The location of the selected record is stored in environmental variable LOCATION. The
|
||
option -o tmp writes the record with key equal to 5 into table tmp, which appears as
|
||
follows:
|
||
|
||
Item Amount Cost Value Description
|
||
|
||
5 99 24 2376 cleaning cloth
|
||
|
||
The next command blanks the contents of tmp, then writes the blanked row back into
|
||
inventory at the location stored earlier at LOCATION:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 291 / Buchseite 281 ====
|
||
select — sorttable 281
|
||
|
||
blank < tmp | replace inventory $LOCATION
|
||
|
||
inventory now appears as follows:
|
||
|
||
Item Amount Cost Value Description
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
3 5 80 400 clamps
|
||
4 23 19 437 plates
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
See Also
|
||
|
||
index, lock, replace, search, unlock
|
||
|
||
select — /rdb Command
|
||
|
||
Output selected rows
|
||
select ‘column condition column-or-value’ < table
|
||
|
||
The command select writes a new file that consists of the rows of table that match the
|
||
expression condition in column.
|
||
|
||
select is a link to the command row. It is included for those users who prefer the name
|
||
select (which is a relational theory name) to row.
|
||
|
||
See Also
|
||
row
|
||
|
||
sorttable — /rdb Command
|
||
|
||
Sort a table by one or more columns
|
||
sorttable [sort options] [columnname ...] < tableorlist
|
||
|
||
The command sorttable uses the COHERENT command sort to sort tableorlist. Unlike sort,
|
||
it knows about table head lines and column names.
|
||
|
||
With sorttable you use the column names rather than column numbers, as in sort.
|
||
sorttable also tells sort to use tabs as field separators, instead of white space (i.e., blanks
|
||
and tabs).
|
||
|
||
sorttable completely sorts by the first column you name. If there are any duplicate values
|
||
in that column, it goes to the second column and sort on those values. It continues across
|
||
the named columns until it either finds a column that consists of unique values, or it runs
|
||
|
||
out of columns. For example. if you sort a ledger on columns Account and Date, sorttable
|
||
sorts the entire table on column Account, and sorts by Date within each account.
|
||
|
||
If no columns are named, sorttable sorts tableorlist by all of its columns from left to right.
|
||
Options
|
||
|
||
sorttable passes all the options you give it to sort. See the entry for sort in the COHERENT
|
||
manual’s Lexicon for details on this command's options.
|
||
|
||
Example
|
||
|
||
Consider table inventory, which is structured as follows:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 292 / Buchseite 282 ====
|
||
282
|
||
|
||
sorttable
|
||
|
||
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
|
||
|
||
To see inventory sorted with the highest Cost items on top, type:
|
||
sorttable -n -r Cost < inventory
|
||
|
||
This produces:
|
||
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
|
||
|
||
Note that Cost is in reverse order (the -r option) and that it was treated as a number (-n
|
||
option) instead of a character string.
|
||
|
||
If you use sorttable frequently, you should carefully study the COHERENT Lexicon entry
|
||
for sort. For example. you can control which columns sorttable sort on. If you name
|
||
several columns, sort sees each column's numbers proceeded by a ‘+’. The ‘+’ means “start
|
||
sorting on this column”, the hyphen ‘-’ means “stop on the next column”. To see this, use
|
||
the -D (debug) option for sorttable. (By the way, it is because sort has a -d option that we
|
||
use a capital -D for the debug option for the /rdb commands). For example, typing
|
||
|
||
sorttable -D Cost Description < inventory
|
||
yields:
|
||
Item Onhand~= Cost Value Description
|
||
|
||
sorttable: command executed: sort -t’ J +2 -3 +4 -5
|
||
2 100 1 100 test tubes
|
||
|
||
4 23 2 51 plates
|
||
|
||
5 99 3 297 cleaning cloth
|
||
|
||
1 3 5 15 rubber gloves
|
||
|
||
3 5 8 40 clamps
|
||
|
||
6 89 18 1602 bunsen burners
|
||
|
||
7 5 175 875 scales
|
||
|
||
The line beginning with sort is the line passed to COHERENT. Note the +1, -2, and so on.
|
||
That tells sort to sort on columns 2 and 4 (where the first column is 0). Thus, sorttable
|
||
correctly turns the column names you type into a sort command by looking up the column
|
||
names in the table head line and converting them to column numbers for the COHERENT
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 293 / Buchseite 283 ====
|
||
soundex 283
|
||
|
||
command sort.
|
||
|
||
People are often confused by sort because it does not behave the way one would expect.
|
||
Study its entry in the COHERENT Lexicon.
|
||
|
||
See Also
|
||
|
||
COHERENT Lexicon: sort
|
||
|
||
soundex — /rdb Command
|
||
Convert a name into soundex code
|
||
soundex < file >_file.x ; index -mb file.x Soundex
|
||
|
||
The command soundex creates a secondary index to file based on Knuth’s soundex code. It
|
||
is used by the /rdb command like to find a name that sounds like another name.
|
||
|
||
The output must be written into file file.xx; then run the command index on column
|
||
Soundex within table.x to ensure a high-speed search.
|
||
|
||
Example
|
||
|
||
Consider table name, which has many similar names in it:
|
||
|
||
Name
|
||
Abraham
|
||
Abraham
|
||
Ackerman
|
||
Actor
|
||
Adams
|
||
Adams
|
||
Adams
|
||
Adams ©
|
||
|
||
Use soundex to create the secondary index file, as follows:
|
||
soundex < name > name.x ; index -mb name.x Soundex
|
||
The soundex’d index file appears as follows:
|
||
|
||
Name Soundex
|
||
|
||
Avila A140
|
||
Avila A140
|
||
Avila A140
|
||
Abraham A160
|
||
Abraham A160
|
||
Aissen A220
|
||
Ajeska A220
|
||
Augustine A223
|
||
|
||
Now you can use the like command to find a name. For example, the command
|
||
|
||
like Manis name
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 294 / Buchseite 284 ====
|
||
284 __splittable
|
||
|
||
produces something like:
|
||
|
||
Name
|
||
Mann
|
||
Mann
|
||
Means
|
||
Mink
|
||
Monahan
|
||
Moniz
|
||
Mooney
|
||
Mooney
|
||
Munoz
|
||
Munoz
|
||
|
||
Or the command
|
||
like Schaffer name
|
||
produces something like:
|
||
|
||
Name
|
||
|
||
Schaeffer
|
||
Schaffer
|
||
Schiffrin
|
||
|
||
See Also
|
||
like
|
||
|
||
splittable — /rdb Command
|
||
Divide a table horizontally
|
||
splittable [-n] table
|
||
|
||
The command splittable uses the COHERENT command split to split table horizontally
|
||
into several smaller tables, each with its own head line. n is the number of rows to write
|
||
into each new table, not counting the two head lines.
|
||
|
||
This command is most useful for report writing because it can split tables into page-sized
|
||
chunks.
|
||
|
||
Like split, splittable creates file names that end with aa, ab, ac, and so on. This give 676
|
||
(26 x 26) possible output files.
|
||
|
||
Example
|
||
|
||
Here is an example using a very short table, called inventory:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 295 / Buchseite 285 ====
|
||
substitute 285
|
||
|
||
Item# Amount Cost Value Description
|
||
1 3 50 150 rubber gloves
|
||
3 100 5 500 test tubes
|
||
3 5 80 400 clamps
|
||
4 23 19 437 plates
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
a 5 175 875 scales
|
||
|
||
The command
|
||
splittable -4 inventory
|
||
|
||
splits inventory into two tables, one with the first four lines of inventory and the other
|
||
with the last three. Each new table also has the same head line as table.
|
||
|
||
The command
|
||
ls inventory*
|
||
shows us that the current directory now contains files:
|
||
|
||
inventory
|
||
inventoryaa
|
||
inventoryab
|
||
|
||
The two new tables are named, respectively, inventoryaa and inventoryab.
|
||
See Also
|
||
COHERENT Lexicon: Is, split
|
||
|
||
Notes
|
||
|
||
Because a COHERENT file can have no more than 14 characters in its name, splittable will
|
||
not work correctly with tables whose names are longer than 12 characters. Caveat utilitor.
|
||
|
||
substitute — /rdb Command
|
||
Replace old string with new string
|
||
substitute oldstring newstring file ...
|
||
|
||
The command substitute replaces oldstring with newstring throughout each file. Because it
|
||
uses the COHERENT command sed, be sure to protect with backslash ‘\" all sed’s special
|
||
characters: **’, ‘*’, 'S’, and ‘\’.
|
||
|
||
Example
|
||
Again, consider table inventory, as follows:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 296 / Buchseite 286 ====
|
||
subtotal
|
||
|
||
Item Amount Cost Value Description
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
3 5 80 400 clamps
|
||
4 23 19 437 plates
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
To replace string rubber with latex throughout inventory, type:
|
||
substitute ‘rubber’ ‘latex’ file
|
||
|
||
inventory now appears as follows:
|
||
|
||
Item Amount Cost Value Description
|
||
|
||
1 3 50 150 latex gloves
|
||
|
||
2 100 5 500 test tubes
|
||
|
||
cK § 5 80 400 clamps
|
||
|
||
4 23 19 437 plates
|
||
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
See Also
|
||
COHERENT Lexicon: sed
|
||
|
||
subtotal — /rdb Command
|
||
|
||
Output subtotals of columns in a table
|
||
subtotal [ -1] [ break-column column... ] < table
|
||
|
||
The command subtotal computes subtotals in each numeric column within table.
|
||
|
||
subtotal uses break-column to mark where computation should begin and end: as long as a
|
||
value in break-column remains the same, the values in the other columns are accumulated.
|
||
When the value in the break-column changes. subtotal prints the value or values
|
||
accumulated since the last break.
|
||
|
||
If no columns are specified on the command line, splittable uses the first. or leftmost.
|
||
column of the table as the break column, and computes subtotals for all other columns.
|
||
|
||
The option -1 prints whole table, not just the subtotals.
|
||
|
||
Example
|
||
There are two forms of output. One produces only the subtotals. If you wanted to see the
|
||
daily subtotals of table journal, type:
|
||
|
||
subtotal Date Debit Credit < journal
|
||
This produces something like the following:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 297 / Buchseite 287 ====
|
||
subtotal 287
|
||
|
||
891222
|
||
891223
|
||
891224
|
||
|
||
25000
|
||
10000
|
||
30000
|
||
|
||
Credit
|
||
|
||
Description
|
||
|
||
Note that columns Description and Account are blank, because they contain non-numeric
|
||
|
||
data.
|
||
|
||
The -1 prints the entire table, as well as the subtotals. For example, the command
|
||
|
||
subtotal -l Date Debit Credit < journal
|
||
|
||
produces:
|
||
|
||
891222
|
||
891222
|
||
|
||
891222
|
||
|
||
891223
|
||
891223
|
||
891223
|
||
|
||
891223
|
||
|
||
891224
|
||
891224
|
||
891224
|
||
|
||
891224
|
||
|
||
Account Debit
|
||
|
||
101 25000
|
||
211.1
|
||
|
||
25000
|
||
150.1 10000
|
||
101
|
||
211.2
|
||
|
||
10000
|
||
130 30000
|
||
201.1
|
||
101
|
||
|
||
30000
|
||
|
||
30000
|
||
|
||
Description
|
||
cash from loan
|
||
loan number #378-14 Bank Amerigold
|
||
|
||
test equipment from Zarkoff
|
||
cash payment
|
||
note payable to Zarkoff Equipment
|
||
|
||
inventory - parts from CCPSC
|
||
accounts payable to CCPSC
|
||
cash payment to CCPSC for parts
|
||
|
||
This lets you see each row as well as the subtotals. This could help you find out when you
|
||
got out of balance.
|
||
|
||
See Also
|
||
|
||
compute, maximum, mean, minimum
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 298 / Buchseite 288 ====
|
||
288 —_‘tableorlist — tabletofact
|
||
|
||
T
|
||
|
||
tableorlist — /rdb Command
|
||
Report whether a file has table or list format
|
||
tableorlist [tableorlist ...] [< tableorlist]
|
||
|
||
The command tableorlist checks whether tableorlist is a table or a list. If it is a list (that is,
|
||
its first character is a newline), then tableorlist prints the string “list” and returns status
|
||
code 1 to the shell; otherwise, it prints the string “table” and returns status code 0.
|
||
|
||
Example
|
||
To check if inventory is a table or list, type:
|
||
|
||
tableorlist inventory
|
||
This prints
|
||
table
|
||
|
||
on the standard output. To check what status value tableorlist returned, type:
|
||
|
||
echo $?
|
||
You'll see:
|
||
|
||
0
|
||
|
||
See Also
|
||
|
||
listtotable, tabletolist
|
||
COHERENT Lexicon: file
|
||
|
||
tabletofact — /rdb Command
|
||
|
||
Converts a table to PROLOG fact-file format
|
||
tabletofact table ... > prologfactfile
|
||
|
||
The command tabletofact converts each table into a file of facts in predicate calculus
|
||
functor form, which can be input to a PROLOG interpreter.
|
||
|
||
Facts
|
||
|
||
PROLOG facts are in the form relationship(subject,object). For example, the fact
|
||
parent (sally, fred)
|
||
|
||
means that “sally is the parent of fred”.
|
||
|
||
PROLOG is a programming language whose name is a contraction of the phrase
|
||
programming in logic. Its input consists of facts, rules, and questions. If you build a data
|
||
base of facts and rules, you can ask questions and get answers. If a question you ask does
|
||
not have a corresponding fact in the data base, PROLOG looks through its rule file to see if
|
||
other facts might logically deduce the fact requested.
|
||
|
||
Example
|
||
Suppose we have these simple table parent
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 299 / Buchseite 289 ====
|
||
tabletofix 289
|
||
|
||
Parent Child
|
||
|
||
the simple table female
|
||
|
||
Name
|
||
|
||
Jane
|
||
Sally
|
||
|
||
and the simple table male:
|
||
|
||
Name
|
||
|
||
Fred
|
||
Mike
|
||
|
||
The command
|
||
|
||
tabletofact parent female male > fact
|
||
produces the following facts:
|
||
|
||
parent (Sally,Fred).
|
||
parent (Mike, Fred).
|
||
parent (Fred,Jane).
|
||
female(Jane).
|
||
female(Sally).
|
||
male(Fred).
|
||
male(Mike).
|
||
|
||
As you can see, the relationship is set by the name of the table, and the subject and object
|
||
(if any) are set by the data in each row.
|
||
|
||
PROLOG can now use its command consult to read this file. If PROLOG had rules about
|
||
father, mother, grandparent, and so on, then it could answer questions like:
|
||
mother(sally,fred)? That fact is not in the data base, but can be deduced from rules like:
|
||
|
||
mother(X,Y) if parent(X,Y¥) and female(X)
|
||
|
||
See Also
|
||
tabletorule
|
||
|
||
Notes
|
||
If you wish to experiment with PROLOG, volume 2 of COHware includes the source code for
|
||
a PROLOG interpreter.
|
||
|
||
tabletofix — /rdb Command
|
||
|
||
Convert /rdb table format to fixed-length format
|
||
tabletofix column=n[r] ... < tableorlist
|
||
|
||
The command tabletofix converts tableorlist from variable-length /rdb format to the fixed-
|
||
length format used by many other data-base management systems.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 300 / Buchseite 290 ====
|
||
290
|
||
|
||
tabletolist
|
||
|
||
tabletofix works by either padding or truncating each column to make it n characters wide.
|
||
If the letter r is used with the width specification, tabletofix right-justifies the column in
|
||
question — that is, it pads the column with leading blanks, assuming any are necessary.
|
||
Otherwise, the column is left justified — that is, it pads the column with trailing blanks.
|
||
|
||
tabletofix also throws away the head lines, as well as all tab characters and blank records.
|
||
|
||
Example
|
||
Consider table journal, which looks like this when viewed with the command see:
|
||
|
||
Date*IAccount *IDebit *ICredit*IDescription$
|
||
|
||
----*I-------*I ----*I ----- “I ----------- $
|
||
820102*T101*125000*I*Icash from loan$
|
||
820102*1211.1*I*1I25000*Iloan number #378-14 Bank Amerigold$
|
||
820103*I150.1*110000*I*Itest equipment from Zarkoff$
|
||
820103*I101*1I5000*I*Icash payment$
|
||
820103*I211.2*I*1I5000*Inote payable to Zarkoff Equipment$
|
||
820104*I130*1I30000*I*Iinventory - parts from CCPSC$
|
||
|
||
The symbol “I indicate a tab, and the symbol $ indicates a newline.
|
||
|
||
Now, let's generate a fixed-length field data base from journal. We'll use the fields Date,
|
||
Account, Credit, and Debit. We'll give the first two fields six bytes each; and we'll give the
|
||
last two fields seven bytes each, right justified:
|
||
|
||
tabletofix Date=6 Account=6 Debit=7r Credit=7r < journal > newjournal
|
||
|
||
This commands writes its output into file newjournal, which appears as follows:
|
||
|
||
820102101 25000
|
||
820102211.1 25000
|
||
820103150.1 10000
|
||
820103101 5000
|
||
820103211.2 5000
|
||
820104130 30000
|
||
|
||
See Also
|
||
|
||
column, fixtotable, see
|
||
|
||
tabletolist — /rdb Command
|
||
|
||
Convert a table to list format
|
||
tabletolist [ -1] < table
|
||
|
||
The command tabletolist converts table to list format.
|
||
|
||
Option -1 tells tabletolist not to write a newline at the beginning of the new list file. This is
|
||
for compatibility with the older list format and for other uses. Note that most /rdb
|
||
commands cannot read a list file if it lacks the initial newline.
|
||
|
||
Example
|
||
|
||
Consider mailtable, which has the following format:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 301 / Buchseite 291 ====
|
||
tabletom4 291
|
||
|
||
Number Name Company Street City State ZIP Phone
|
||
|
||
1 Ronald McDonald McDonald’s 123 Mac Attack Memphis
|
||
TENN 30000 (111) 222-3333
|
||
|
||
2 Chiquita Banana United Brands Uno Avenito De La
|
||
Revolution San Jose Costa Rica 123456789 1234
|
||
|
||
As you can see, the information in each row is often too wide for the screen; these data
|
||
would be better stored in a list-format file. To convert mailtable to list format. type the
|
||
following:
|
||
|
||
tabletolist < mailtable
|
||
This writes the following to the standard output:
|
||
|
||
<newline>
|
||
|
||
Number 1
|
||
|
||
Name Ronald McDonald
|
||
Company McDonald’s
|
||
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
|
||
|
||
See Also
|
||
listtotable
|
||
tabletom4 — /rdb Command
|
||
|
||
Convert a table to m4 define-file format
|
||
tabletom4 < table > definefile
|
||
|
||
The command tabletom4 converts a two-column table into a file of define statements that
|
||
can be input to the COHERENT macro processor m4. Define macros are in the form
|
||
define(old,new).
|
||
|
||
m4 can do many things, including word-for-word substitution. It can be used for language
|
||
translation (in a stiff, inflexible way) and for other conversions of data bases.
|
||
|
||
The definefile that tabletom4 produces is required by the /rdb command translate. Only
|
||
words that have a corresponding translation in the second column will be put into
|
||
definefile. In this way, you can use the file before you have all of the translations entered.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 302 / Buchseite 292 ====
|
||
292
|
||
|
||
tabletorule
|
||
|
||
Example
|
||
Consider the simple translation table ed.t:
|
||
|
||
English Deutch
|
||
|
||
» | Ich
|
||
love liebe
|
||
you dich
|
||
widgit
|
||
|
||
The following command converts ed.t to m4 format and writes its output into file ed:
|
||
tabletom4 < ed.t > ed
|
||
ed now contains the following:
|
||
|
||
define(I,Ich)
|
||
define( love, liebe)
|
||
define(you,dich)
|
||
|
||
Note that widgit was not converted because it did not have a translation string in the
|
||
second column of the table. ed can now be used by m4 or translate. For example, if file
|
||
text contains the following:
|
||
|
||
I love you.
|
||
The command
|
||
|
||
m4 ed text
|
||
writes
|
||
|
||
Ich liebe dich.
|
||
|
||
onto the standard output.
|
||
See Also
|
||
|
||
translate
|
||
COHERENT Tutorials: Introduction to the m4 Macro Processor
|
||
COHERENT Lexicon: m4
|
||
|
||
tabletorule — /rdb Command
|
||
|
||
Convert a table to PROLOG rule-file format
|
||
tabletorule table ... > prologrulefile
|
||
|
||
The command tabletorule converts each table into a file of rules in predicate-calculus
|
||
implication form that can be input to a PROLOG interpreter.
|
||
|
||
PROLOG rules are in the form:
|
||
relationship(X,Y) :- class(X), relationship(X,Y).
|
||
For example
|
||
mother(X,Y) :- female(X), parent(X,Y).
|
||
means that “X is the mother of Y, if X is female and X is the parent of Y.”
|
||
|
||
PROLOG is a programming language used for artificial-intelligence applications. Its name is
|
||
a contraction of the phrase programming in logic. Input to PROLOG consists of facts. rules.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 303 / Buchseite 293 ====
|
||
tabletorule 293
|
||
|
||
and questions. If you build a data base of facts and rules, you can ask questions and get
|
||
answers. If a question you ask does not have a corresponding fact in the data base,
|
||
PROLOG will look through its rule file to see if other facts might logically deduce the fact
|
||
requested.
|
||
|
||
Example
|
||
Suppose we have the simple table parent
|
||
Parent Child
|
||
|
||
Mike Fred
|
||
Fred Jane
|
||
|
||
the simple table female
|
||
|
||
Name
|
||
|
||
Jane
|
||
Sally
|
||
|
||
the simple table male
|
||
|
||
Name
|
||
|
||
Fred
|
||
Mike
|
||
|
||
and the simple table ruletable:
|
||
|
||
mother(X,Y¥) female(X), parent(X,Y)
|
||
The command
|
||
tabletorule ruletable > rule
|
||
writes the following into file rule:
|
||
mother(X,Y¥) :- female(X), parent(X,Y).
|
||
|
||
Now PROLOG can use its consult command to read rule. It could then answer questions
|
||
like:
|
||
|
||
mother (sally, fred)?
|
||
|
||
See Also
|
||
tabletofact
|
||
|
||
Notes
|
||
|
||
If you wish to experiment with PROLOG, volume 2 of COHware includes the source code for
|
||
a PROLOG interpreter.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 304 / Buchseite 294 ====
|
||
294
|
||
|
||
tabletosed
|
||
|
||
tabletosed — /rdb Command
|
||
|
||
Convert table format to sed file format
|
||
tabletosed < table > sedfile
|
||
|
||
The command tabletosed converts a two-column table into a file of sed statements that can
|
||
be input to the sed stream editor. sed macros are in the form:
|
||
|
||
s/old/new/g
|
||
|
||
sed can do many things, including word-for-word substitution. sedfile produced is used by
|
||
the /rdb command translate. It can be used for language translation (in a stiff, inflexible
|
||
way) and for other conversions of data bases.
|
||
|
||
Example
|
||
|
||
Suppose we have a simple translation table, called ed.t
|
||
|
||
English Deutch
|
||
|
||
a § Ich
|
||
love liebe
|
||
you dich
|
||
widgit
|
||
|
||
The following command turns ed.t into a file of sed editing instructions, called ed.sed.1:
|
||
tabletosed < ed.t > ed.sed.1
|
||
ed.sed.1 appears as follows:
|
||
|
||
s/I/Ich/g
|
||
s/love/liebe/g
|
||
s/you/dich/g
|
||
|
||
We can now use ed.sed.1 with sed or translate. For example, if file text contains the
|
||
sentence
|
||
|
||
I love you.
|
||
then typing
|
||
sed -f ed.sed.1 text
|
||
prints the following on the standard output:
|
||
Ich liebe dich.
|
||
You can also use this command to construct form letters.
|
||
|
||
See Also
|
||
|
||
translate
|
||
|
||
COHERENT Tutorials: Introduction to the sed Stream Editor
|
||
COHERENT Lexicon: sed
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 305 / Buchseite 295 ====
|
||
tabletostruct 295
|
||
|
||
tabletostruct — /rdb Command
|
||
Convert table to C-language struct declaration
|
||
tabletostruct tag name < table > table.h
|
||
|
||
The command tabletostruct converts a standard /rdb table into a C-language struct
|
||
declaration. struct is the C language's record format.
|
||
|
||
tabletostruct is useful for writing table-driven C code. The tables used by your programs
|
||
can be manipulated by the data base and your users, or by nonprogrammer developers
|
||
(engineers, experts, managers, operators), then converted to a struct and compiled into the
|
||
C code for high-speed access.
|
||
|
||
tag gives the struct tag for declaring other variables. name is the struct name to reference
|
||
the structure values.
|
||
|
||
Please note once code compiled from a table, changing that tables no longer affects the
|
||
program until you recompile it. Therefore, you gain maximum speed at the price of
|
||
recompiling the system and losing the flexibility of being able to modify the tables during
|
||
execution.
|
||
|
||
Example
|
||
|
||
Here we start with a simple table. convert it to struct, make it a header file, and compile it
|
||
into a simple program that prints out each field. To begin, consider table table. which is
|
||
structured as followed:
|
||
|
||
A B c
|
||
|
||
1 2 3
|
||
|
||
The following commands converts table to a struct and writes it into file table.h:
|
||
tabletostruct Table table < table > table.h
|
||
|
||
table.h now holds the following:
|
||
|
||
struct Table
|
||
|
||
{
|
||
|
||
char *A;
|
||
|
||
char *B;
|
||
|
||
char *C;
|
||
|
||
} table [] =
|
||
|
||
{ "1", "2","3" }
|
||
The following gives some C code that prints the contents of the struct we call Table:
|
||
#include "table.h"
|
||
|
||
main ()
|
||
|
||
{
|
||
printf ("A=%s\n", table[0].A);
|
||
printf (“B=%s\n", table[0].B);
|
||
printf ("C=%s\n", table[0].C);
|
||
|
||
}
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 306 / Buchseite 296 ====
|
||
296
|
||
|
||
tabletotbl — tax
|
||
|
||
When compiled with the command
|
||
cc -o printtable printtable.o
|
||
the newly created command printtable yields the following output:
|
||
A=1
|
||
B=2
|
||
C=3
|
||
|
||
Note that the data are stored in an array of structs, so we must give a subscript for each
|
||
row we want.
|
||
|
||
We can also put the command tabletostruct into a Makefile, so that the COHERENT
|
||
command make can automate the building of the struct and its compilation. For example:
|
||
|
||
printtable: table.h printtable.o
|
||
cc -o printtable printtable.o
|
||
|
||
table.h: table
|
||
tabletostruct Table table < table > table.h
|
||
|
||
This says that the printable program depends upon table.h being up to date, and table.h
|
||
depends upon table table being up to date. If you had modified table since the last
|
||
compile, make reexecutes the command tabletostruct.
|
||
|
||
See Also
|
||
|
||
listtotable, tabletolist
|
||
COHERENT Tutorials: The C Language, The make Programming Discipline
|
||
COHERENT Lexicon: array, make, struct
|
||
|
||
tabletotb! — /rdb Command
|
||
|
||
Convert /rdb table format to UNIX tbl/nroff format
|
||
tabletotbl < tablefile > tbifile
|
||
|
||
The command tabletotbl converts an /rdb table to UNIX tbl format. tbl is a UNIX program
|
||
that formats tables for the nroff/troff formatting and typesetting programs.
|
||
|
||
Notes
|
||
The COHERENT system's version of nroff and troff do not yet support tbl.
|
||
|
||
tax — /rdb Command
|
||
|
||
Compute tax from income and tax table
|
||
tax income < taxtable
|
||
|
||
The command tax reads tax-table information from taxtable and computes taxes from it.
|
||
income is the income you wish to check. taxtable must be in the three-column format
|
||
shown in the following example.
|
||
|
||
tax writes to the standard output the computed tax rounded off to the nearest dollar.
|
||
Example
|
||
|
||
The following table, X83, holds the federal income tax for single taxpayers for 1983
|
||
(Schedule X):
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 307 / Buchseite 297 ====
|
||
termput 297
|
||
|
||
income tax percent
|
||
2300 0 11
|
||
3400 121 12
|
||
4400 251 15
|
||
6500 566 15
|
||
8500 866 17
|
||
|
||
10800 1257 19
|
||
12900 1656 21
|
||
15000 2097 24
|
||
18200 2865 28
|
||
23500 4349 32
|
||
28800 6045 36
|
||
34100 7953 40
|
||
41500 10913 45
|
||
55300 17123 50
|
||
|
||
If your taxable income is $20,000, type the following:
|
||
tax 20000 < x83
|
||
taxtable writes the following to the standard output:
|
||
3369
|
||
|
||
That is, according to the data in X83, a single person with an income of $20,000 in 1983
|
||
owed the IRS $3,369.
|
||
|
||
You can also catch the output in a shell variable, like this:
|
||
TAX=‘tax 20000 < X83‘
|
||
|
||
This initializes environmental variable TAX to 3369. You can now use TAX to write the tax
|
||
into a table. For example:
|
||
|
||
compute “line == 35 { value = $TAX }" < forml1040
|
||
|
||
Note that this command uses the quotation mark (") instead of the apostrophe (’), because
|
||
we want the shell to substitute the value of tax where we have typed STAX. To quote
|
||
something within quotation marks ("), you must use apostrophes (’).
|
||
|
||
Notes
|
||
|
||
Please note that the tax tables included with /rdb are for 1987. Mark Williams Company
|
||
makes no claim as to their accuracy, or their usefulness in computing current taxes.
|
||
Caveat utilitor!
|
||
|
||
termput — /rdb Command
|
||
Get terminal capability from /etc/termcap file
|
||
termput capability
|
||
|
||
The command termput reads and returns the current capabilities for your terminal, as set
|
||
in file /etc/termcap. A two-letter capability code is followed by a string of characters that,
|
||
when sent to the terminal screen, turn on or off that capability. This assumes, of course,
|
||
that your terminal is properly described in /etc/termcap.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 308 / Buchseite 298 ====
|
||
298
|
||
|
||
termput
|
||
|
||
Capabilities
|
||
|
||
The capabilities are two-letter codes recognized by termcap. Here are some examples:
|
||
|
||
cl Clear the terminal screen
|
||
|
||
cm Cursor movement
|
||
|
||
so Start standout mode (e.g., reverse video)
|
||
se End standout mode
|
||
|
||
Using most of these codes is straightforward: just echo the appropriate code to the terminal
|
||
to get the effect you want. Cursor movement, however, is more complicated; the cursor-
|
||
movement code that termput returns must be edited to hold the row and column to which
|
||
you wish to move the cursor. For details, see the manual page for the command cursor.
|
||
|
||
Example
|
||
You can embed termput in a shell script to help invoke reverse video, blinking, and any
|
||
other your terminal has defined in /etc/termcap.
|
||
|
||
The first example clears the screen:
|
||
termput cl
|
||
|
||
The next example puts the screen into reverse video:
|
||
termput se
|
||
|
||
and the following turns off reverse video:
|
||
termput so
|
||
|
||
You can use termput to initialize environmental variables, which you can then invoke in a
|
||
shell script. This is much faster than making repeated calls to termput. To set up these
|
||
shell variables, insert the following commands your file SHOME/. profile:
|
||
|
||
end alternate character set - graphics
|
||
start alternate character set - graphics
|
||
|
||
export AE=‘termput ae’
|
||
export AS=‘termput as’
|
||
|
||
clear the screen
|
||
|
||
cursor movement - for the cursor command
|
||
start blinking mode
|
||
|
||
turn off all attributes
|
||
|
||
end stand out mode
|
||
|
||
start stand out mode
|
||
|
||
end underline mode
|
||
|
||
start underline mode
|
||
|
||
export CLEAR=‘termput cl’
|
||
export CURSOR=‘termput cm’
|
||
export MB=‘termput mb‘
|
||
export ME=‘termput me’
|
||
export SE=‘termput se’
|
||
export SO=‘termput so’
|
||
export UE=‘termput ue’
|
||
export US=‘termput us’
|
||
|
||
RRR RR RHR HH
|
||
|
||
Once this is set up, you can use these environmental variables in your shell program. For
|
||
example. if you want a message to stand out, bracket it with $SO and SSE:
|
||
|
||
echo "${SO} LOGOFF NOW ${SE}"
|
||
|
||
See Also
|
||
|
||
clear, cursor, screen
|
||
COHERENT Lexicon: console, stty, termcap, terminal-independent operations
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 309 / Buchseite 299 ====
|
||
testall —timesearch 299
|
||
|
||
testall — /rdb Command
|
||
Test all /rdb programs in directory SRDB/demo
|
||
testall [ > testall.new ]
|
||
|
||
The command testall runs most of the /rdb programs with the files in the $RDB/demo.
|
||
You should run testall in directory $RDB/demo, because the test files are there.
|
||
|
||
testall writes the output of each example to the standard output. We suggest that you
|
||
store the output in file S$RDB/demo/testall.old. Thereafter, you can check if the behavior
|
||
of a test program has changed, by using the COHERENT command diff to compare the
|
||
output of testall with the contents of SRDB/demo/testall.old. /rdb performs this testing
|
||
when the /rdb database is installed on a computer, and when code is changed.
|
||
|
||
Example
|
||
|
||
First go to the demo directory, assuming the path is /usr/rdb/demo:
|
||
|
||
cd /usr/rdb/demo
|
||
testall > testall.new
|
||
diff testall.old testall.new
|
||
|
||
The command diff finds and displays any differences between testfile.old and testfile.new.
|
||
After careful checking, if differences are correct, type:
|
||
|
||
mv testall.new testall.old
|
||
or
|
||
rm testall.new
|
||
|
||
This saves space. because these files are large.
|
||
|
||
See Also
|
||
COHERENT Lexicon: diff
|
||
|
||
testsearch — /rdb Command
|
||
Test the fast-access methods
|
||
testsearch
|
||
|
||
The command testsearch runs and times the /rdb commands index and search.
|
||
|
||
You must cd to directory $RDB/demo before you run testsearch, because it uses tables
|
||
unixtable and unixlist in that directory. If you wish, you can edit testsearch to time the
|
||
search of a big list or table that you are manipulating.
|
||
|
||
See Also
|
||
|
||
testall, timesearch
|
||
COHERENT Lexicon: time
|
||
|
||
timesearch — /rdb Command
|
||
|
||
Time fast-access methods
|
||
timesearch [ > timesearch.new ]
|
||
|
||
The command timesearch runs and times the /rdb commands index and search. Its
|
||
purpose is to find the fastest fast-access method for a given situation. Theory often fails
|
||
when working with access methods; a sequential search by the select command may prove
|
||
faster than one of the fast-access methods when the overhead of building the index is
|
||
included in the evaluation.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 310 / Buchseite 300 ====
|
||
300 todaysdate — total
|
||
|
||
timesearch is in directory $RDB/demo rather than in $RDB/bin because it is written to
|
||
test just the tables unixtable and unixlist. Because it is a shell script. you can edit it to
|
||
test searching on a big table you are manipulating.
|
||
|
||
Example
|
||
The following command test-runs timesearch:
|
||
|
||
cd $RDB/demo ; timesearch | more
|
||
timesearch writes to the standard output the outputs of the /rdb commands index and
|
||
search, plus the output of the COHERENT command time that it uses to time the
|
||
programs.
|
||
See Also
|
||
|
||
index, search, testall, testsearch
|
||
COHERENT Lexicon: time
|
||
COHERENT tutorials: Introducing sh, the Bourne Shell
|
||
|
||
todaysdate — /rdb Command
|
||
Print today’s date in YYMMDD format
|
||
todaysdate
|
||
|
||
The command todaysdate displays the today’s date in the form: YYMMDD. Under /rdb, this
|
||
format is called the “computer format.” It is the best format for entering data in a column
|
||
because it sorts correctly.
|
||
|
||
See Also
|
||
|
||
computedate, gregorian, julian
|
||
COHERENT Lexicon: date, time, timezone
|
||
|
||
total — /rdb Command
|
||
Sum a column
|
||
total [ -1] [column ...] < table
|
||
|
||
The command total adds up the values in each column in table. If no column is named on
|
||
the command line, it totals every column in table.
|
||
|
||
The option -1 prints the entire table as well as the total for each column.
|
||
|
||
Several other commands behave just like total, except that the value they produce is not a
|
||
|
||
total but: datatype. maximum, minimum, mean, precision, width, length, and so on.
|
||
|
||
The all call the same program, but decide what to print depending upon the name used to
|
||
|
||
call it.
|
||
|
||
Example
|
||
|
||
There are two formats. Without the option -l, total just gives the head lines and the total
|
||
|
||
line. For example, to find the totals of columns Debit and Credit in table journal, type:
|
||
total Debit Credit < journal
|
||
|
||
This returns something like:
|
||
Date Account Debit Credit Description
|
||
|
||
65000 65000
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 311 / Buchseite 301 ====
|
||
translate 301
|
||
|
||
However, if you wish to see the whole table. as in a report. type:
|
||
total -1 Debit Credit < ledger
|
||
|
||
This returns something like:
|
||
|
||
Account Date Debit Credit
|
||
101 890102 25000
|
||
|
||
101 890103 5000
|
||
101 890104 15000
|
||
130 890104 30000
|
||
|
||
150.1 890103 10000
|
||
|
||
201.1 890104 15000
|
||
211.1 890102 25000
|
||
211.2 890103 5000
|
||
|
||
65000 65000
|
||
|
||
See Also
|
||
maximum, mean, minimum, subtotal
|
||
|
||
translate — /rdb Command
|
||
Word-for-word substitution using a translation file
|
||
translate language < text > translatedtext
|
||
|
||
The command translate performs word-for-word replacement on text. You can use it to
|
||
perform crude translations from one language to another.
|
||
|
||
translate uses either m4, sed, or both. For m4, translate needs a define file generated by
|
||
the /rdb command tabletom4; the define file must be named language. For sed, it needs a
|
||
preprocessing file and can also use a postprocessing file, both generated by the command
|
||
tabletosed; the preprocessing file must be named language.sed.1, and the postprocessing
|
||
file must be named language.sed.2. See the manual pages for these /rdb commands for a
|
||
description of the sort of table they require as input.
|
||
|
||
Example
|
||
Suppose we have a simple translation for English to Deutsch (German), called ed.t:
|
||
|
||
English Deutsch
|
||
|
||
I Ich
|
||
love liebe
|
||
you dich
|
||
widgit
|
||
|
||
The command
|
||
tabletom4 < ed.t > ed
|
||
generates the m4 definition file ed, which contains the following:
|
||
|
||
define(I,Ich)
|
||
define(love, liebe)
|
||
define(you,dich)
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 312 / Buchseite 302 ====
|
||
302
|
||
|
||
trim
|
||
|
||
trim —
|
||
|
||
Note that tabletom4 did not convert widgit because this word had no translation in the
|
||
table.
|
||
|
||
Now, if file text contains the sentence
|
||
|
||
I love you.
|
||
|
||
you can use translate to translate it into German. Typing
|
||
translate ed text
|
||
|
||
prints the following on the standard output:
|
||
Ich liebe dich.
|
||
|
||
translate has also been used in a biomedical expert system. The idea is to convert each
|
||
word into its value after looking it up in a table. For example:
|
||
|
||
Var Value
|
||
age 42
|
||
weight 80
|
||
|
||
This is something the Lisp language does frequently.
|
||
translate can also be used to construct form letters.
|
||
|
||
See Also
|
||
|
||
tabletom4, tabletosed, word
|
||
COHERENT Lexicon: m4, sed
|
||
|
||
/tdb Command
|
||
Trim excess white space from a table
|
||
trim [-[1]n[1n] col...][-r[n] col...][-t’c"]...< table
|
||
|
||
The command trim trims excess white space from each column in table. This lets you print
|
||
a wide table with the minimum width for each column. Please note that trim removes all
|
||
tabs from table, which renders it unreadable by any /rdb command, including trim itself.
|
||
|
||
trim without any options does the best it can to squeeze table without discarding any
|
||
information. It make each column as wide as its widest column name or data item. You
|
||
can also tell trim to reduce a column's width, even if it has to throw away characters.
|
||
|
||
Note that trim trim all columns, even if some are listed with the options. Most other /rdb
|
||
commands, such as justify, affect only the columns named on the command line — unless
|
||
none are listed, in which case they do the same thing to all of them.
|
||
|
||
Options
|
||
|
||
trim recognizes the following options:
|
||
n The number of characters remaining after the trim.
|
||
|
||
-ncolumn...
|
||
Return only n characters from the left of column.
|
||
|
||
-In column ...
|
||
Return only n characters from the left of column.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 313 / Buchseite 303 ====
|
||
trim 303
|
||
|
||
-rn column...
|
||
|
||
Return only n characters from the right of column.
|
||
|
||
-t‘c’ | Use character c as the column separator. For example, you may want to keep the
|
||
|
||
tab character so that the table can be used by other /rdb commands.
|
||
|
||
When use this option, remember that the COHERENT shell gives special treatment
|
||
|
||
to certain characters, such as the tab and the vertical bar ‘|’.
|
||
these characters by enclosing them between apostrophes.
|
||
|
||
You must quote
|
||
|
||
The above options affect the columns named. The options are sticky, which means that you
|
||
|
||
can follow an option with as many column names as you wish.
|
||
|
||
Example
|
||
|
||
Consider, once again, table inventory, which appears as follows:
|
||
|
||
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
|
||
| 5 175.00 875.00 scales
|
||
|
||
To trim it, type:
|
||
trim < inventory
|
||
This prints the following:
|
||
|
||
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
|
||
” 5 175.00 875.00 scales
|
||
|
||
Note that the length of the column names Item and Amount determined the width of their
|
||
|
||
columns, but in all other columns the data determined the width.
|
||
|
||
To examine what trim did exactly, you can use the command see For example:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 314 / Buchseite 304 ====
|
||
304
|
||
|
||
trim
|
||
|
||
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
|
||
|
||
Note that there are no tabs “I. This table is only for printing. Don't input or pipe this
|
||
output to another /rdb command unless you use the -t option, which retains the tab as a
|
||
column separator. :
|
||
|
||
We can further squeeze the table with the options -n, -In, and -rn. For example. the
|
||
command
|
||
|
||
trim -1 Item < inventory
|
||
|
||
reduces column Item to only one character. This produces the following:
|
||
|
||
I Amount Cost Value Description
|
||
|
||
1 3 5.00 15.00 rubber gloves
|
||
2 100 0.50 50.00 test tubes
|
||
|
||
3 bt 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
|
||
4 5 175.00 875.00 scales
|
||
|
||
Note that to reduce Item to one character, trim had to throw away all but the ‘I’ of the
|
||
column name Item. Note that the other columns were trimmed normally.
|
||
|
||
Because options are sticky, you can name several columns after one option: For example,
|
||
the command
|
||
|
||
trim -5 Item Amount Cost Description < inventory
|
||
|
||
reduces the four named columns to a maximum of five characters. This produces the
|
||
following:
|
||
|
||
1 3 5.00 15.00 rubbe
|
||
2 100 0.50 50,00 test
|
||
|
||
3 5 8.00 40.00 clamp
|
||
4 23 1.98 45.54 plate
|
||
5 99 2.45 242.55 clean
|
||
6 89 14.75 1312.75 bunse
|
||
¥ 4 5 175 875.00 scale
|
||
|
||
You can use the option -rn both to save the n right characters of a column and to line up
|
||
numbers on the right. For example, the command
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 315 / Buchseite 305 ====
|
||
trim 305
|
||
|
||
trim -r3 Amount < inventory
|
||
|
||
produces:
|
||
|
||
Item Amo 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
|
||
|
||
Note that the column name Amount has been reduced to Amo. Also, the column is right
|
||
justified as a result of removing the right three characters of each field in the column.
|
||
|
||
A complex trim might be done like this:
|
||
trim -1 Item -r3 Amount -r5 Cost -17 Value Description < inventory
|
||
|
||
This command produces:
|
||
|
||
I Amo Cost Value Descrip
|
||
1 3 5.00 15.00 rubber
|
||
2 100 0.50 50.00 test tu
|
||
3 5 8.00 40.00 clamps
|
||
4 23 1.98 45.54 plates
|
||
5 99 2.45 242.55 cleanin
|
||
6 89 14.75 1312.75 bunsen
|
||
7 5 175.0 875.00 scales
|
||
|
||
We have squeezed this table a lot.
|
||
|
||
We have been working with an unjustified table. What if the table had been justified? First
|
||
let's justify the table:
|
||
|
||
justify < inventory > tmp ; mv tmp inventory
|
||
Now inventory is justified, as follows:
|
||
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
|
||
|
||
Now, if we trim, you see:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 316 / Buchseite 306 ====
|
||
306 —s trim
|
||
|
||
Item Amount Cost Va
|
||
|
||
. 2
|
||
14.7 13
|
||
175.0 8
|
||
|
||
lue Descr
|
||
|
||
15.00 rubbe:
|
||
50.00 test
|
||
40.00 clamp
|
||
45.54 plate
|
||
42.55 clean
|
||
|
||
iption
|
||
|
||
Xr gloves
|
||
tubes
|
||
|
||
's
|
||
|
||
s
|
||
|
||
ing cloth
|
||
|
||
12.75 bunsen burners
|
||
75.00 scales
|
||
|
||
This mess results from trimming the right characters in the right justified columns Item,
|
||
Amount, and Cost. This preserved the blank spaces, which are to the left in each column,
|
||
and threw away the data. One way to fix this is to tell trim that the columns are right
|
||
justified, like this:
|
||
|
||
This produces:
|
||
Amount Cost
|
||
|
||
Item
|
||
|
||
1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
|
||
23
|
||
99
|
||
89
|
||
5
|
||
|
||
1312.75
|
||
0 875,00
|
||
|
||
trim -r Item Amount Cost < inventory
|
||
|
||
Description
|
||
rubber gloves
|
||
test tubes
|
||
clamps
|
||
|
||
plates
|
||
cleaning cloth
|
||
bunsen burners
|
||
scales
|
||
|
||
You can also compress the file before piping it into trim. For further compression, use the
|
||
command:
|
||
|
||
This produces;
|
||
I Amo Cost
|
||
1 3 5.00
|
||
2 100 0.50
|
||
3 t 8,00
|
||
4 23 1.98
|
||
5 99 2.45
|
||
6 89 14,75
|
||
FT 5 175.00
|
||
See Also
|
||
|
||
Value
|
||
15.00
|
||
50,00
|
||
40.00
|
||
45.54
|
||
242.55
|
||
1312.75
|
||
875.00
|
||
|
||
Description
|
||
rubber glov
|
||
test tubes
|
||
clamps
|
||
plates
|
||
cleaning cl
|
||
bunsen burn
|
||
scales
|
||
|
||
compresss, justify, trimblank
|
||
|
||
LEXICON
|
||
|
||
trim -rl Item -r3 Amount -r6 Cost -111 Description < inventory
|
||
|
||
==== PDF-Seite 317 / Buchseite 307 ====
|
||
trimblank —tset 307
|
||
|
||
trimblank — /rdb Command
|
||
Remove leading and trailing blanks from a string
|
||
trimblank [string] [ <_file ]
|
||
|
||
The command trimblank trims all white-space characters from the beginning and end of
|
||
string. This is useful in shell programming, in which you need to trim white space from a
|
||
string that has been padded (justified) with space characters.
|
||
|
||
Example
|
||
The command
|
||
|
||
echo ' here is the good stuff * | trimblank
|
||
|
||
prints:
|
||
here is the good stuff
|
||
|
||
See Also
|
||
compresss, justify, trim
|
||
|
||
tset — /rdb Command
|
||
Fetch termcap entry for a terminal type
|
||
tset [ TERM ]
|
||
|
||
The command tset duplicates the Berkeley UNIX program by the same name. It finds the
|
||
entry in file /etc/termcap for terminal type TERM. If no terminal type is named on the
|
||
command line, it returns the termcap entry for the type of terminal you are now using.
|
||
|
||
You can use tset to initialize an environmental variable, which you then filter with other
|
||
/rdb or COHERENT commands.
|
||
|
||
Example
|
||
|
||
If you are working on your computer's console, your terminal type is probably ansipc. In
|
||
that case. the command tset prints the following on the standard output:
|
||
|
||
t:al=\E[L:am:bs:bt=\E[Z:bw:cd=\E[0O:ce=\E[K:ch=\E[ %itd‘:cl=\E[20:\
|
||
:om=\E[%itd; $dH:co#80:cs=\E[%itd; tdr:cv=\E[%itdd:dl=\E[M:ho=\E[H:\
|
||
ris=\E[25f\E[7m 1=Line_L 2=Line_R 3=D_Ln 4=Und_Ln 5=Undo 6=Und_Blk 7=Tag\
|
||
8=Join 9=Rptx 10=Rptd \E[m\E[H:\
|
||
:kO=\E[0x:k1=\E[1x:k2=\E[2x:k3=\E[3x:k4=\E[4x:\
|
||
:k5=\E[5x:k6=\E[6x:k7=\E[7x:k8=\E[8x:k9=\E[9x:\
|
||
:kb=*h:kd=\E[B:kh=\E[H:k1=\E[D:kr=\E[C:ku=\E[A:\
|
||
|
||
:1i#24:11=\E[24; 1H:hd=\E[C:se=\E[m:sf=\E[S:sg#0:so=\E[7m:sr=\E[T:\
|
||
tte=\Ec:ue=\E[m:up=\E[A:us=\E[4m:\
|
||
:KI=\E[5x:KD=\E[3x:Kd=\E[P:KB=\E[6x:KU=\E[4x:Ku=\E[@:KM=\E[7x:KJ=\E[8x:\
|
||
:Kt=\E[Z:KT=\t:KL=\E[ 1x: KR=\E[2x:KP=\E[U:Kp=\E[V:KX=\E[9x:KC=\E[ 0x:
|
||
:KE=\E[24H: KW=*F : Kw=*R:Kr="N:do=\E[B:
|
||
|
||
The command
|
||
TERMCAP=‘tset’
|
||
|
||
initializes the environmental variable TERMCAP to your terminal's termcap entry. Storing
|
||
this information in an environmental variable greatly speeds processing of programs that
|
||
manipulate the screen.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 318 / Buchseite 308 ====
|
||
308 tset
|
||
|
||
See Also
|
||
|
||
termput
|
||
COHERENT Lexicon: termcap
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 319 / Buchseite 309 ====
|
||
union 309
|
||
|
||
union — /rdb Command
|
||
|
||
Concatenate tables
|
||
union tableorlist ... [-] [< tableorlist ]
|
||
|
||
The command union concatenates all of the tableorlists named on the command to form a
|
||
new table or list. The new table or list contains all the rows in the first input table or list
|
||
followed by the rows of the second, and so on. The input tables or lists must have the same
|
||
number of columns. It is best that the columns have the same name and the same type of
|
||
data, in the same order.
|
||
|
||
The hyphen ‘-’ tells where in the list of files the standard input is to go. This gives you the
|
||
freedom to use union in a pipe and to place the input file anywhere in the output.
|
||
|
||
Example
|
||
Consider table journal, as follows:
|
||
|
||
Date Amount Account Ref Description
|
||
820107 14.00 meal v meal with jones
|
||
820119 81.72 vitamin c sundown vitamins
|
||
820121 20.83 meal Vv meal with scott
|
||
820121 2500.00 keogh c keogh payment
|
||
820125 99.00 dues Vv dues to uni-ops
|
||
|
||
and table carexpense, as follows:
|
||
|
||
Date Amount Account Ref Description
|
||
|
||
820113 101.62 car v car repairs
|
||
|
||
820114 81.80 insur c car insurance allstate
|
||
820114 93.00 car c car registration dmv
|
||
|
||
The command
|
||
union journal carexpense
|
||
produces the following output:
|
||
Date Amount Account Ref Description
|
||
|
||
820107 14.00 meal meal with jones
|
||
|
||
820119 81.72 vitamin sundown vitamins
|
||
820121 20.83 meal meal with scott
|
||
|
||
820121 2500.00 keogh keogh payment
|
||
|
||
820125 99.00 dues dues to uni-ops
|
||
|
||
820113 101.62 car car repairs
|
||
|
||
820114 81.80 insur car insurance allstate
|
||
820114 93.00 car car registration dmv
|
||
|
||
aaceadcgas¢
|
||
|
||
The command
|
||
|
||
echo journal | union - carexpense
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 320 / Buchseite 310 ====
|
||
310
|
||
|
||
uniondict — unlock
|
||
|
||
accomplishes the same thing as the previous example, but shows demonstrates how to use
|
||
union with a pipe.
|
||
See Also
|
||
|
||
jointable, split
|
||
COHERENT Lexicon: cut, paste
|
||
|
||
uniondict — /rdb Command
|
||
|
||
Combine three tables into translation dictionary
|
||
uniondict langtolang > definefile
|
||
|
||
The command uniondict creates an m4 define-file out of three tables. langtolang is a two-
|
||
letter code that indicates which language is being translated to which; for example. ed
|
||
stands for “English to German” (Deutsch).
|
||
|
||
uniondict expects one table of lower-case letters, such as ed.low, and one of all capital
|
||
letters, such as ed.allcap, and builds its own table with initial capitals. Finally uniondict
|
||
uses the /rdb command tabletom4 to create a definefile for m4.
|
||
|
||
Example
|
||
To generate a definefile for English-to-German translation, type the command:
|
||
uniondict ed
|
||
|
||
If the two precursor files already exist, then this command generates a new file named ed
|
||
that can be used by translate.
|
||
See Also
|
||
|
||
tabletom4, translate, word
|
||
COHERENT Lexicon: m4
|
||
|
||
unlock — /rdb Command
|
||
|
||
Unlock a record or field of a file
|
||
unlock tableorlist processid from to indexfrom indexto
|
||
|
||
The command unlock unlocks a record or file by removing a row from a common unlock
|
||
file. File /tmp/Ltableorlist contains one line for each locked record or field plus processid of
|
||
the process that locked it. from and to give, respectively, the offsets of the beginning and
|
||
end of the locked record or field; and indexfrom and indexto give, respectively, the offsets of
|
||
the beginning and end of the row or field's entry in the secondary index file.
|
||
|
||
Example
|
||
Let us use unlock on table inventory, which is as follows:
|
||
|
||
Item Amount Cost Value Description
|
||
1 3 50 150 rubber gloves
|
||
2 100 5 500 test tubes
|
||
3 5 80 400 clamps
|
||
4 23 19 437 plates
|
||
5 99 24 2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
First, we use the /rdb command seek to locate the record and return the offset and size:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 321 / Buchseite 311 ====
|
||
update.inv 311
|
||
|
||
LOCATION=‘echo 5 | seek -mb inventory Item‘
|
||
|
||
The above command returns the offset and size of column Item in row 5 of table inventory,
|
||
and writes the informatio into environmental variable LOCATION. When we look at the
|
||
contents of LOCATION, we see the following:
|
||
|
||
207 245 0 8
|
||
|
||
This means that the record begins 207 bytes into the file, ends 245 bytes into the file, and
|
||
therefore is 38 bytes long.
|
||
|
||
Now we can call unlock to unlock the record:
|
||
unlock inventory $$ $LOCATION
|
||
|
||
Note that we use the environmental variable SLOCATION to supply the location. We also
|
||
use the shell's built-in variable $$ to write the process identifier onto the command line.
|
||
|
||
Let's see what the lock file looks like. Since we're locking table inventory, the lock file is
|
||
named Linventory. If we type the command:
|
||
|
||
cat /tmp/Linventory
|
||
we see the message:
|
||
cat: cannot open /tmp/Linventory
|
||
unlock removes the lock file if it removes the last lock line.
|
||
See Also
|
||
lock, seek
|
||
|
||
update.inv — /rdb Command
|
||
Multi-user update with screen form and record locking
|
||
update.inv
|
||
The command update.inv is a sample shell program that demonstrates several features of
|
||
/rdb, including multiuser input, fast access, screen-form input. and record locking. It
|
||
updates an inventory file named inv that is in the directory $RDB/demo Use it to see how
|
||
to use the COHERENT shell to tie /rdb and COHERENT programs together to form fast.
|
||
multiuser, large-file applications.
|
||
The environmental variable TERM must be set to the correct name of your terminal, as
|
||
described in the COHERENT system file /etc/termcap. To make the reverse video and
|
||
underlining work, you will have to initialize environmental variables in your .profile.
|
||
|
||
Example
|
||
ced to directory $RDB/demo and run update.inv:
|
||
|
||
cd rdb/demo
|
||
update.inv
|
||
|
||
You'll the following template on your screen:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 322 / Buchseite 312 ====
|
||
312 update.rdb
|
||
|
||
Makeapile, Inc. Inventory Update Mon Jan 8, 1990
|
||
Item Number: (or hit Return key to exit.)
|
||
Item Cost Value Description
|
||
|
||
Amount Onhand:
|
||
|
||
Try the program for yourself and study the program source.
|
||
|
||
See Also
|
||
lock, search, seek, replace, unlock
|
||
COHERENT Lexicon: TERM, termcap
|
||
|
||
update.rdb — /rdb Command
|
||
|
||
Display and edit records in any sized file
|
||
update.rdb [-1 -m[bhirs] -v] tableorlist [keycolumn ... ]
|
||
|
||
The command update.rdb lets you find a record in tableorlist, display it, and update it.
|
||
|
||
update.rdb can find a record in any of several different ways: by moving up and down in the
|
||
file, by record number, by matching a string pattern in a record, and a fast-access method
|
||
search.
|
||
|
||
update.rdb lets you use a text editor to edit the record you find. To lock out other users
|
||
who might be looking at your file, update.rdb uses the /rdb command lock to lock the
|
||
record being edited. When you finish editing, update.rdb replaces the edited record back
|
||
into tableorlist.
|
||
|
||
If the new record is smaller than the old record, it adds space characters to the end of the
|
||
last column to pad out the record. If the new record is larger than the old record, it trims
|
||
trailing and leading spaces from the columns. If update.rdb cannot find enough blank
|
||
spaces to trim, it does not replace the record, but appends it to the end of the table and
|
||
updates the fast-access method indexes, if any. If this happens, you have several options:
|
||
You can reedit the record. You can append the record to the end of the file using enter and
|
||
delete the current record. You can also pad each record with extra spaces so that there will
|
||
be room when you do updates. To add padding, use the command pad.
|
||
|
||
Because update.rdb replaces an edited record to where the original was extracted, you do
|
||
not have to rebuilt entirely any fast-access indexes that fileorlist owns. As long as you don't
|
||
change the key columns, the fast-access methods can still find the records. This can mean
|
||
a considerable savings in the time needed to update a record.
|
||
|
||
Also, update.rdb can handle any sized file, whereas the text editors and word processors
|
||
mostly cannot handle files of more than a few thousand characters.
|
||
|
||
Options
|
||
|
||
update.rdb recognizes the following options:
|
||
|
||
-1 No lock. Do not lock the record by blanking out the record in the file while updating.
|
||
This is much faster than using record-locking; but it is truly safe if you are the only
|
||
|
||
person who can update tableorlist. If more than one person can access tableorlist at the
|
||
same time, do not use this option.
|
||
|
||
-m Fast access method. See the manual page for the /rdb command search for a
|
||
description of these options.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 323 / Buchseite 313 ====
|
||
update.rdb 313
|
||
|
||
-v Verbose. With this option, update.rdb prints information about what it is doing
|
||
during each step of updating a record. You can use this information to find the
|
||
bottlenecks in updating; for example, you may find that you are not using the best
|
||
method of accessing the records you wish to update.
|
||
|
||
Getting
|
||
|
||
To invoke update.rdb to edit tableorlist, simply type:
|
||
|
||
update.rdb tableorlist
|
||
update.rdb prompt you with a'‘>’.
|
||
|
||
You can exit from update.rdb by any of three methods: Type <ctrl-D>, type “quit”, or simply
|
||
type ‘q' (because update.rdb looks at only the first character of the one-word commands).
|
||
|
||
Finally, the kill character on your terminal (usually <ctrl-C>) kills the program, as it does
|
||
other COHERENT commands.
|
||
|
||
Help Menu
|
||
|
||
update.rdb has a help menu built into it. To see it, type help at the ‘>’ prompt. You will
|
||
see the following:
|
||
|
||
Command Description | update.rdb [-l -m{bhirs] -1l] file
|
||
|
||
CTRL-d exit, hold down CTRL key and press d
|
||
|
||
(see quit below)
|
||
Return key display next record
|
||
number display record number you enter
|
||
|
||
(number = 1,29,...)
|
||
+number move forward the number of records in the file
|
||
-number move backwards the number of records in the file
|
||
/pattern find next record with pattern
|
||
=key find records with key matching what you type
|
||
{command execute the unix command while still in update.rdb
|
||
tenter file enter new records at end of the file
|
||
|
||
(You need only type the first letter of the commands below)
|
||
|
||
delete delete the current record
|
||
m[bhirs] [col] set up fast access method for key column
|
||
b=binary, h=hash, i=index, r=record, s=sequential
|
||
|
||
lock lock update.rdb record by blanking (toggle, true)
|
||
search key find records with matching key
|
||
|
||
help help list displayed (this help list)
|
||
|
||
quit quit (also cntl-d)
|
||
|
||
update.rdb update current record, allows you to edit, replace
|
||
verbose report internal actions (toggle, false)
|
||
|
||
Finding a Record
|
||
|
||
There are several ways to find the record you want.
|
||
|
||
When update.rdb comes up, it displays the first record in tableorlist. To move to the next
|
||
record, simply press <Return>. You can move forward any number of records with a plus
|
||
sign and a number, for example. +5; and you can move backwards with a minus sign and a
|
||
number, for example: -16. You can also select a specific record by typing its number.
|
||
Record numbers are displayed with each record.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 324 / Buchseite 314 ====
|
||
314 update.rdb
|
||
|
||
Pattern Search
|
||
|
||
If you try to go beyond the last record or before the first record, update.rdb warns you.
|
||
|
||
You can also search for a record that has a given string by typing a slash character followed
|
||
by string. For example, to search for pattern “Ronald”, type: /Ronald. update.rdb searches
|
||
forward starting with the next record, then wraps around and goes to the first record in the
|
||
file and continues till it finds a match or returns to the current record.
|
||
|
||
Fast-Access Methods
|
||
|
||
update.rdb can use fast-access methods to find a record within tableorlist. You can turn on
|
||
the fast-access methods in either of two ways:
|
||
|
||
1.
|
||
|
||
2.
|
||
|
||
Use the appropriate option on the command line. For example, the command
|
||
update.rdb -mh inventory Description
|
||
|
||
invokes the fast-access method for table inventory.
|
||
|
||
Type the appropriate option at update.rdb's prompt. For example, typing
|
||
mh Description
|
||
|
||
at update.rdb's ‘>’ prompt invokes the fast-access method for column Description.
|
||
Both ways tell update.rdb which method to use and which column is the key column.
|
||
|
||
Once invoked, you can search with either the = or s commands. For example:
|
||
|
||
> =keyvalue
|
||
> s keyvalue
|
||
|
||
Updating
|
||
To update the current record, simply type:
|
||
|
||
> update
|
||
|
||
Just the letter u is sufficient.
|
||
|
||
The steps in using update.rdb are as follows:
|
||
|
||
1.
|
||
2.
|
||
|
||
3.
|
||
|
||
Invoke update.rdb with the name of the table or list to be edited.
|
||
|
||
Find the record you want by entering its row number, a string it contains, or through a
|
||
fast-access method.
|
||
|
||
When the record is found, type u to update it.
|
||
|
||
update.rdb copies the record to a file with a header so that it is a one record table or
|
||
list.
|
||
|
||
update.rdb replaces the selected record with a string of blanks of the same length,
|
||
hold the record's place within its table, and to lock out other users.
|
||
|
||
update.rdb then copies the temporary record file to a backup file in case you damage
|
||
it.
|
||
|
||
update.rdb then reads environmental variable EDITOR and calls the editor it names to
|
||
let you edit the record you selected. If EDITOR is not set in your environment, it
|
||
invokes vi by default.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 325 / Buchseite 315 ====
|
||
uppercase 315
|
||
|
||
8. Use the editor to edit the record.
|
||
|
||
9. When you exit your editor, update.rdb returns the edited the record into its table or
|
||
list. It adds or removes trailing spaces to make the record fit into the same amount of
|
||
space it previously occupied in its table or list. If the record doesn't fit into its old
|
||
space, update.rdb lets you choose whether to re-edit the record, or append it to the
|
||
end of the table or list.
|
||
|
||
You can also validate a record before leaving your editor by typing:
|
||
validate file.v < file
|
||
|
||
See the COHERENT Lexicon entries for the editor you are using for information on how to
|
||
pass that command to the shell without exiting from the editor. The entry for the command
|
||
validate in this manual describes how it works.
|
||
|
||
Other Useful Commands
|
||
|
||
If you need to see the current record again because it has run off the screen, simply type a
|
||
period at update.rdb’s prompt.
|
||
|
||
To execute a COHERENT shell command, type an exclamation point and the command you
|
||
wish to execute. For example, to execute the command Is from within update.rdb, type
|
||
|
||
> Ils
|
||
This feature also lets you append new records to a table while still within update.rdb. To do
|
||
so, just type:
|
||
> tenter thisfilename
|
||
When you leave the enter command, you will be back in update.rdb.
|
||
You can also index the file you are working with from within update.rdb. Just type:
|
||
> tindex -mi filename keycolumn
|
||
|
||
This command creates index file fllename.i, which update.rdb can then use for fast-access
|
||
searching of file you are updating.
|
||
|
||
Padding
|
||
|
||
When you set up a table that you intend to update, you probably should pad it — that is,
|
||
add extra space characters to each record. Then you can add characters to a record and
|
||
update.rdb will trim off the space characters to fit it back into the file. For details, see the
|
||
manual page for the command pad.
|
||
|
||
Notes
|
||
|
||
This command is named update.rdb rather than update, as in other implementations of
|
||
/rdb, to avoid clashing with the COHERENT command update, which does something very
|
||
different.
|
||
|
||
uppercase — /rdb Command
|
||
Convert input to all upper-case characters
|
||
uppercase [string ...] [< file]
|
||
The command uppercase converts to to upper-case characters every letter in string. If you
|
||
|
||
do not pass it a string, it reads the standard input. It uses the COHERENT command tr to
|
||
perform conversion.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 326 / Buchseite 316 ====
|
||
316
|
||
|
||
uppercase
|
||
|
||
Example
|
||
|
||
Here we convert a string to upper case:
|
||
uppercase little words
|
||
|
||
This displays
|
||
LITTLE WORDS
|
||
|
||
on the standard output.
|
||
|
||
If the file lowers contains the text
|
||
these are all lowercase.
|
||
|
||
then the command
|
||
uppercase < lowers
|
||
|
||
prints the following on the standard output:
|
||
THESE ARE ALL LOWERCASE,
|
||
|
||
See Also
|
||
cap, lowercase
|
||
COHERENT Lexicon: tr
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 327 / Buchseite 317 ====
|
||
validate 317
|
||
|
||
validate — /rdb Command
|
||
Find invalid data
|
||
validate ‘pattern { action} ...' < tableorlist
|
||
The command validate checks your tables and a list of invalid data. It also prints messages
|
||
of your choosing, and shows you the line that caused the error. It is almost identical to a
|
||
combination of the commands row and compute.
|
||
|
||
validate passes your commands to awk after it has converted your column names to $1,
|
||
$2. and so on, which is how awk refers to columns.
|
||
|
||
pattern is a logical condition that indicates invalidity in the data; for example, it may give
|
||
values that are negative and should not be, or greater than they should be. action is what
|
||
to do about it; usually, this is to print a message.
|
||
|
||
Example
|
||
|
||
The first example is simple. Once again, consider table inventory, which is as follows:
|
||
Item# Onhand Cost Value Description
|
||
|
||
1 3 50 150 rubber gloves
|
||
2 100 x 500 test tubes
|
||
|
||
3 5 80 -400 clamps
|
||
|
||
4 23 19 437 plates
|
||
|
||
5 -99 24 -2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
Several invalid values have crept into this table. You might wish to check that no item in
|
||
column Onhand is less than zero. To do so, type the command:
|
||
|
||
validate ‘Onhand < 0 {print “negative Onhand in line “ NR}’ < badinventory
|
||
This prints the following on the standard output:
|
||
Item# Onhand Cost Value Description
|
||
|
||
1 3 50 150 rubber gloves
|
||
|
||
2 100 x 500 test tubes
|
||
negative Onhand in line 3
|
||
|
||
3 -5 80 -400 clamps
|
||
|
||
4 23 19 437 plates
|
||
negative Onhand in line 5
|
||
|
||
5 -99 24 -2376 cleaning cloth
|
||
|
||
6 89 147 13083 bunsen burners
|
||
|
||
7 5 175 875 scales
|
||
|
||
The variable NR means number of record or row. This variable is built into awk, which
|
||
replaces it with the number of the line it is processing.
|
||
|
||
The next example is complex. Note that if you wish, you can write a command line for
|
||
validate into a file, to create a customized validation command. You can put many tests
|
||
and messages in one validation file. For example, the following command file, called
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 328 / Buchseite 318 ====
|
||
318
|
||
|
||
ve
|
||
|
||
validateinv, thoroughly checks table inventory:
|
||
echo validating badinventory
|
||
|
||
validate ‘{if (Onhand < 0 ) print “negative Onhand in line “ NR; \
|
||
if (Value < 0 ) print "negative Value in line " NR; \
|
||
if (Cost - /[A-Za-z]/) print “letter in Cost in line " NR; }’ \
|
||
< badinventory
|
||
|
||
To validate table inventory, just type:
|
||
|
||
validating badinventory
|
||
This prints the following on the standard output:
|
||
Item# Onhand Cost Value Description
|
||
|
||
1 3 50 150 rubber gloves
|
||
letter in Cost in line 2
|
||
2 100 x 500 test tubes
|
||
|
||
negative Onhand in line 3
|
||
negative Value in line 3
|
||
3 =5 80 -400 clamps
|
||
4 23 19 437 plates
|
||
negative Onhand in line 5
|
||
negative Value in line 5
|
||
|
||
5 -99 24 -2376 cleaning cloth
|
||
6 89 147 13083 bunsen burners
|
||
7 5 175 875 scales
|
||
|
||
You may wish to redirect the output of validate to a file, bring it into your editor, and
|
||
correct the errors and remove the error lines as you go. To make it easier to find those error
|
||
lines in the editor, you could have all error lines contain a string that is easy to find, such
|
||
as ERROR.
|
||
|
||
If you only want to see the error lines, use the command row.
|
||
|
||
See Also
|
||
Logical Conditions
|
||
|
||
compute, row
|
||
COHERENT Tutorials: Introduction to the awk Language
|
||
|
||
ve — /rdb Command
|
||
|
||
Visually edit a table
|
||
ve [table [-n{n] -fc -me -i -s [file] -h [file] -a [file] -v [file}]}[-b]
|
||
|
||
ve is an editor that is designed to edit tables in a multi-user environment. Because it is
|
||
designed to work with tables, it understands rows and columns; and because it is designed
|
||
for a multi-user environment, it knows how to lock records and perform other useful tasks
|
||
to protect the integrity of of your data.
|
||
|
||
ve defines a ruw, or record, as containing a fixed number of columns, or flelds. It defines a
|
||
field as being a string delimited by an exclusive column separation character. Normally, the
|
||
first two rows in a ve table are header records that describe the columns in each row. Each
|
||
field in the first header record names its column; fields in the second header record are
|
||
hyphens '-'. When you invoke ve without an argument. it displays a menu of on-line ve
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 329 / Buchseite 319 ====
|
||
ve 319
|
||
|
||
help topics and instructions.
|
||
|
||
table is the table you wish to edit. When you name a table on the command line, all other
|
||
arguments must follow it. If table does not exist. ve create sthe necessary header records
|
||
from a screen file or a header table.
|
||
|
||
Options
|
||
|
||
ve recognizes the following options:
|
||
|
||
-b
|
||
|
||
-nn
|
||
|
||
-fe
|
||
|
||
-mc
|
||
|
||
-s file
|
||
|
||
Use the terminal's highlighting capability. If specified. ve does its best to
|
||
emphasize non-data text and the on-line help file's keywords by displaying them in
|
||
high intensity. This may produce odd results if the entry in file /ete/termcap for
|
||
your terminal is incorrect or missing. or if your terminal type is set incorrectly.
|
||
|
||
Use automatic record numbering. ve assumes that the data in the first column of
|
||
each record are unique numbers, and keeps track of the largest value in this
|
||
column. As you add new records to the table, ve increments this number and
|
||
stores it in the first column of the new record.
|
||
|
||
When you specify n, ve begins numbering records at that value. For example, -
|
||
n2001 means, “Use automatic record numbering and begin the numbers at 2001.”
|
||
|
||
Use the character c to delimit columns instead of the default tab character. With
|
||
the exception of the screen file, all files associated with the ve table must use the
|
||
same column separation character.
|
||
|
||
Invoke ve in mode c, where c is one of the following:
|
||
|
||
i Insert mode
|
||
n Next mode
|
||
/ Search mode
|
||
|
||
ve returns to this mode after each successful write. Invoking ve in insert mode is
|
||
convenient when entering data.
|
||
|
||
Initialize the table. ve maintains a private sequential index of all records in a table,
|
||
so it can track the records in use and the records that have been deleted during an
|
||
editing session. It also uses this index to clean up the table when the edit session
|
||
is over. If the table is modified by a program other than ve, then you must use the
|
||
-i switch during the next ve edit session to reinitialize its private index. You can
|
||
use this index for fast searching by record number if each record has a number and
|
||
no records are ever deleted.
|
||
|
||
If the current directory contains any files that follow ve's naming convention data-c,
|
||
where -c is a file-option switch (-s, -h, -a, -v), ve incorporates them automatically
|
||
into the command line before it processes the argument list. You must name on
|
||
the command line all files that not named according to this convention; please note
|
||
that this overrides the inclusion of any default names in the command line.
|
||
|
||
Tell ve to use file as the screen file, which contains a template of how you want the
|
||
screen to appear. The entire screen file should not exceed 23 lines. ve scans the
|
||
screen file for column names enclosed between angle brackets (<>) and displays the
|
||
data in those columns between the brackets. Both brackets must be on the same
|
||
line. If file is used to initialize the table, all column names must be listed:
|
||
otherwise, excluding a column name from a template also keeps data in those
|
||
columns from being viewed, sought. or modified. If a column name is preceded by
|
||
an exciamation point, ve lets you search for that column's data and display them.
|
||
but no user can modify them.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 330 / Buchseite 320 ====
|
||
320 ve
|
||
|
||
-h file
|
||
|
||
-a file
|
||
|
||
-vfile
|
||
|
||
The header records are in file. If no file is named, ve assumes that the header
|
||
records are in file data-h. ve can create a header file only when the table is
|
||
initialized with a screen file.
|
||
|
||
If the audit table does not exist. tell ve to create it and write it into file. If you do not
|
||
name file, ve writes the audit table into data-a.
|
||
|
||
ve audits a table by recording each addition, modification, and deletion you make
|
||
to it, and storing this information in its audit table. The audit table looks like the
|
||
table, with the addition of two columns in the beginning of each record: the time
|
||
stamp column and the modification code column.
|
||
|
||
The first column of each row in the table must be a unique number so that rows
|
||
can be tracked accurately. ve manages these numbers and assigns new ones to the
|
||
rows you add. If the table already exists, ve begins record numbering at the largest
|
||
record number in the table plus one; for new tables, ve begins record numbering at
|
||
one.
|
||
|
||
Each time you add a record (code a), change a record (code c), or delete one (code
|
||
d), ve records in the audit table the date and time, the modification code, and the
|
||
number of the record. When you change or delete a record, ve also stores it in the
|
||
audit table the data that the record contained before you changed or deleted it.
|
||
|
||
Use file as the validation table. If you do not name file, ve uses data-v by default.
|
||
If the validation table does not exist, ve creates it. then uses itself to edit the new
|
||
validation table so you can enter validation requirements for desired columns before
|
||
you edit the table.
|
||
|
||
When you include a validation table in the command line, ve checks the data as it is
|
||
entered into columns, which are specified in the validation table, to make sure they meet
|
||
certain requirements.
|
||
|
||
The first header record of the validation table contains a name column. a character column,
|
||
a length column, and a table look-up column, in that order.
|
||
|
||
name column
|
||
|
||
This names a column from the table being validated.
|
||
|
||
character column
|
||
|
||
Give the valid characters or ranges of characters for data in this column Characters
|
||
and ranges must be separated by commas (,). Ranges or characters that are
|
||
preceded by an ‘!’ exclude that range or character from the valid list. For example.
|
||
the validation string a-z,!y,1-9,#,., .., means that all lower-case characters with the
|
||
exception of y are valid, as are numerals from 1 to 9, pound symbols, periods,
|
||
blanks, and commas. By contrast, the string !0-9 excludes all numerals from the
|
||
column.
|
||
|
||
length column
|
||
|
||
LEXICON
|
||
|
||
Set the length limit of the column, as follows:
|
||
<n The column cannot exceed n characters in length.
|
||
|
||
>n The column cannot be less than n characters long. The < and > symbols
|
||
can be used with each other. For example, >10,<28 specifies that the
|
||
length of the data in this column must be at least 11 and not more than 27
|
||
characters long.
|
||
|
||
=n The column can contain only n characters.
|
||
|
||
==== PDF-Seite 331 / Buchseite 321 ====
|
||
ve 321
|
||
|
||
! Zero indicator. This can used with any of the above symbols to indicate
|
||
that the column can also have a length of zero. For example, !.=5 means
|
||
that the column can contain zero characters; if it does not contain zero
|
||
characters, it must contain exactly five characters.
|
||
|
||
table look-up column
|
||
Tell ve to check the data entered against the contents of an existing table. When
|
||
the name of the table is preceded by ‘!’, data entered in the column must not be in
|
||
the table; otherwise they must be in the table.
|
||
|
||
You can create an index table with the command vindex. It names them after the
|
||
column you are vindexing. which is called the key column. If the name of the key
|
||
column is longer than 11 characters, vindex truncates the name to 11 characters.
|
||
It also converts blanks in the key column's name to ‘_’.
|
||
|
||
For example, the specification /name tells ve to check the data against a table
|
||
comprised of all text located in a column named name. If the data are not found in
|
||
the table, then it passes validation.
|
||
|
||
Commands
|
||
|
||
The following table gives the ve edit commands. ve uses two modes when editing a table:
|
||
command mode and insert mode. Commands that switch ve from command to insert mode
|
||
are indicated by <ESC>. The ESC (escape) key switches ve from insert to command mode.
|
||
|
||
The commands c and d commands require targets. A target is the destination for the
|
||
command being executed. For example, the command dfa means, “delete text from the
|
||
cursor up to and including the first a character encountered.” In this case. the target
|
||
command is f. In the table, commands that can be used as targets for the c and d
|
||
commands are indicated by (t).
|
||
|
||
Some commands recognize a number that indicates how many times it should execute. For
|
||
example, the command 51 means, “Move right five characters"; the command 3rP means,
|
||
“Replace the next three characters with the character P.” Counts may also be used with
|
||
targets; for example, command c2w means, “Change the next two words.” Commands that
|
||
recognize counts are indicated by a (c).
|
||
|
||
Command Description
|
||
Atext<ESC>.. .. Append text at field end
|
||
atext<ESC> Append text after cursor
|
||
|
||
B.. Back field (c)
|
||
|
||
b.. Back word (t.c)
|
||
C<ESC> Change to field end
|
||
e<ESC> Change to target
|
||
|
||
D. Delete to field end
|
||
|
||
d.. Delete to target
|
||
|
||
dd Delete record
|
||
|
||
e.. End of word (t.c)
|
||
|
||
Fx... Find x left (t.c)
|
||
|
||
fe; Find x right (t.c)
|
||
|
||
Gi Go to last record (c)
|
||
|
||
H. ..-First field
|
||
|
||
h.. ... Left character (t.c)
|
||
Itext<ESC> insert text at field start
|
||
itext<ESC> insert text before cursor
|
||
j- Down field (c)
|
||
|
||
kK. Up field (c)
|
||
|
||
L.. ... Last field
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 332 / Buchseite 322 ====
|
||
-Right character (t.c)
|
||
-Mark search field
|
||
-Unmark search field
|
||
-Get next record
|
||
. Open new record
|
||
.Open new field
|
||
-Put yanked record
|
||
..--Put yanked field
|
||
---- Quit ve
|
||
.- Replace
|
||
-Replace with x
|
||
. Redraw the screen
|
||
. Substitute text (c)
|
||
. Table display
|
||
-Undo last command
|
||
- Validation display
|
||
. Write record
|
||
-Next word (t.c)
|
||
- Delete character (c)
|
||
-Yank current record
|
||
-Yank current field
|
||
.... Write record & quit
|
||
....Field display
|
||
-Repeat F/f cmd (t)
|
||
a -Start of field (t)
|
||
engee -End of field (t)
|
||
/text<ESC>. . Search for text
|
||
/<ESC> .... Repeat search
|
||
-Get preceding record
|
||
-Execute the shell
|
||
-Shell escape
|
||
....Repeat shell escape
|
||
....Scroll field left
|
||
-Scroll field right
|
||
-Help file(s) display
|
||
«Next field (c)
|
||
-Next field (c)
|
||
. Right character(t.c)
|
||
|
||
The next table gives two other kinds of ve commands — colon commands and control-key
|
||
commands, all of which map directly to commands in given in the previous table. Colon
|
||
commands are provided for users familiar with vi or ed. Control-key commands let you
|
||
define command macros by specifying the control key character and the command or
|
||
commands to be executed each time the control key is hit. These definitions, or macros are
|
||
defined in the /rdb-formatted file .verc located in the your home directory. If there is no
|
||
-verc file, then the default control-key commands apply. If you are in insert mode when a
|
||
control key is hit, ve attempts to restore that mode after successful execution of the macro.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 333 / Buchseite 323 ====
|
||
vilock — vindex 323
|
||
|
||
Command Maps to Command Maps to
|
||
th{elp] # <ctrl-A> #
|
||
:nfext] n <ctril-R> s
|
||
:o[pen] Oo <ctrl-T> t
|
||
:qluit]) q <ctrl-Q> ZZ
|
||
:s[hell] <ctrl-S> %
|
||
:w{rite] <ctrl-W> Ww
|
||
:!emd !emd <ctrl-V> v
|
||
ot! HL <ctrl-D> dd
|
||
See Also
|
||
vindex
|
||
|
||
COHERENT Lexicon: elvis, vi
|
||
|
||
vilock — /rdb Command
|
||
Lock a table before editing, unlock afterward
|
||
vilock tableorlist
|
||
|
||
The command vilock stops others from editing the same file you are editing. It locks the
|
||
table, invokes the vi with which you can edit the table, then unlocks the table when you
|
||
have finished editing.
|
||
|
||
To lock tableorlist, vilock changes its name to LOCKtableorlist; this is a temporary file that
|
||
exists only as long as you are editing. vilock then invokes vi for LOCKtableorlist. When
|
||
you finish editing and exit from vi, vilock moves LOCKtableorlist back to its original name.
|
||
If anyone else trys to edit tableorlist while you are editing it with vilock, he receives a
|
||
message that the file is locked or missing.
|
||
|
||
See Also
|
||
lock, unlock, ve
|
||
COHERENT Lexicon: elvis, vi
|
||
|
||
vindex — /rdb Command
|
||
Create and display ve look-up tables
|
||
vindex table [ key-column [: decode-column ] ... ]]
|
||
|
||
The command vindex creates and displays tables composed of columns in ve tables. These
|
||
tables are used by ve when validating column entries. table names the ve table. When no
|
||
options are specified, vindex displays the contents of all existing column tables associated
|
||
with table.
|
||
|
||
For each key-column, vindex collects the text from that column and stores it in two files;
|
||
each is prefixed by the name of the key-column and is suffixed by -A or -B. If the name of
|
||
the key column exceeds 14 characters, the table-name prefix is truncated to 14 characters.
|
||
Key column whose names contain blanks must be surrounded by quotation marks; blanks
|
||
are converted to underscores ‘_’ in the table name. These files are referred to in the fourth
|
||
|
||
column of ve validation files by the table-name prefix.
|
||
|
||
When the colon *:' argument follows a key-column name, the column name following this
|
||
argument is assumed to be the name of a decode-column. As key-column text is collected in
|
||
the table, the associated vindex links the decode-column’'s text to it as a cross-reference.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 334 / Buchseite 324 ====
|
||
324 ~—-vindex
|
||
|
||
Example
|
||
The following vindex command create a look-up table for the key columns Snumber and
|
||
State in table personnel; it also cross-references the information in Snumber with the text
|
||
|
||
in the decode-column Employee:
|
||
vindex personnel “Snumber" : Employee State
|
||
|
||
The resulting tables are named Snumber and State.
|
||
|
||
See Also
|
||
ve
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 335 / Buchseite 325 ====
|
||
whatis — whatwill 325
|
||
|
||
W
|
||
|
||
whatis — /rdb Command
|
||
Display the command description and syntax
|
||
whatis command
|
||
|
||
The command whatis displays the description and syntax of command. It resembles the
|
||
COHERENT command help, except that it handles /rdb commands.
|
||
|
||
Example
|
||
|
||
The command
|
||
whatis column
|
||
displays the following:
|
||
|
||
column - display columns of a table in any order
|
||
column column ... < tableorlist
|
||
|
||
And the command
|
||
|
||
whatis whatis
|
||
|
||
displays:
|
||
whatis - displays the command description and syntax
|
||
whatis command
|
||
|
||
See Also
|
||
|
||
whatwill
|
||
|
||
COHERENT Lexicon: help, man
|
||
|
||
whatwill — /rdb Command
|
||
Display commands with functions in description
|
||
whatwill function
|
||
|
||
The command whatwill displays the description and syntax of the command that performs
|
||
function. It resembles the Berkeley UNIX command appropos. It also resembles the /rdb
|
||
command whatis except that it seeks function anywhere in the name of the command, the
|
||
description, and the syntax. For example, if you ask for total, whatwill returns both total
|
||
and subtotal.
|
||
|
||
Example
|
||
|
||
The first command looks for information about columns:
|
||
whatwill column
|
||
This returns:
|
||
|
||
column - display columns of a table in any order
|
||
column column ... < table
|
||
|
||
And the command
|
||
whatwill total
|
||
|
||
returns:
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 336 / Buchseite 326 ====
|
||
326 widest — word
|
||
|
||
subtotal - outputs the subtotal of columns in a table
|
||
subtotal { -l J[ break-column column ...] < table
|
||
total - sums up each column selected and displays
|
||
total { -1 J{ column ... ] < table
|
||
|
||
See Also
|
||
|
||
whatis
|
||
|
||
COHERENT Lexicon: help, man
|
||
|
||
widest — /rdb Command
|
||
Output the width of the widest entries in a table
|
||
widest < table
|
||
|
||
The command widest reads table and writes to the standard output a second table that
|
||
gives the width of the widest entry in each column.
|
||
Example
|
||
|
||
The command
|
||
|
||
widest < inventory
|
||
reads table inventory and writes something like the following to the standard output:
|
||
Item Amount Cost Value Description
|
||
|
||
4 6 4 5 14
|
||
|
||
Each number is the width, in characters, inventory’s the widest entry in that column. You
|
||
can use this information for formatting. /rdb does not require a schema because it gets the
|
||
parameters of the tables from the tables themselves.
|
||
|
||
See Also
|
||
|
||
width
|
||
|
||
width — /rdb Command
|
||
Display the width of each column
|
||
width [-1][column...] < table
|
||
|
||
The command width displays the maximum width of each column in table. If no column is
|
||
named, it returns this information for every column in table. The option -1 displays the
|
||
entire table as well as information about the maximum width in each column.
|
||
|
||
Example
|
||
|
||
For an example of this command, see the entry for total.
|
||
|
||
See Also
|
||
total, widest
|
||
|
||
word — /rdb Command
|
||
Convert text file into list of unique words
|
||
word < text > table
|
||
|
||
The command word reads text converts it to a list of the unique words it contains, and
|
||
writes the list to the standard output. You can use word to help construct tables for the
|
||
/rdb command translate.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 337 / Buchseite 327 ====
|
||
word 327
|
||
|
||
Example
|
||
If you were to type the above paragraph into a file called FOO, the command
|
||
|
||
word < FOO
|
||
would print the following to the standard output:
|
||
|
||
The
|
||
|
||
You
|
||
|
||
a
|
||
|
||
and
|
||
|
||
can
|
||
command
|
||
construct
|
||
contains
|
||
converts
|
||
for
|
||
help
|
||
|
||
it
|
||
|
||
list
|
||
|
||
of
|
||
output
|
||
rdb
|
||
reads
|
||
standard
|
||
tables
|
||
text
|
||
the
|
||
|
||
to
|
||
unique
|
||
use
|
||
word
|
||
words
|
||
writes
|
||
|
||
See Also
|
||
translate
|
||
COHERENT Lexicon: sort, tr, uniq
|
||
|
||
Notes
|
||
|
||
Because word is a shell script. you can modify it to map upper-case characters to lower
|
||
case, if you wish.
|
||
|
||
LEXICON
|
||
|
||
==== PDF-Seite 338 / Buchseite 328 ====
|
||
328 /rdb Relational DBMS
|
||
|
||
/rdb
|
||
documentation............... 154
|
||
function library .......... -. 154
|
||
selected commands....... ee
|
||
/rdb & shell programming. . . . 87
|
||
frdb Headers 352333% & 6 8 Sater + « 222
|
||
|
||
account
|
||
|
||
subtotal... 2.2... 0... eee eee 217
|
||
accounting period
|
||
|
||
COs! ecg 6 5 GE LEON OR Fi RS ETRS S 187
|
||
accounting system ..........0005 170
|
||
accounting terms...............
|
||
|
||
accounts payable .
|
||
BOE Foie se noe merece ee eee ce 8
|
||
|
||
add column to table ............. 170
|
||
add head'to:table « oissciss a 4 6 weiss % S 223
|
||
|
||
BOUNISE sas 54 KH NSE ZG SE
|
||
|
||
ANSISQL.......
|
||
apostrophe. . .
|
||
append......
|
||
append row
|
||
|
||
INDEX
|
||
|
||
append row to table... .......... 172
|
||
append row-number column ........ 249
|
||
BBE vies 6 0 Sramebers BOMB MOREE zp A 135
|
||
BEQV sak ie FS WN YY Sob HERS OES ee 135
|
||
arithmetic
|
||
|
||
COLURAN 6 « wxenaie yw a aranaums % % WBNS
|
||
|
||
Gate <6 6 sek 4 eG ele
|
||
artificial intelligence ......
|
||
ASCII .
|
||
ascii. .
|
||
ASCII
|
||
|
||
convert from integer... ......... 186
|
||
Ashton-Tate..............000. 200
|
||
assembly language ............... 4
|
||
Mbps So TS SS RGSS RF Seeders 110
|
||
atoi(). .. ee ee ee ee 155
|
||
BUGIE TANS) 6 coc5i6 in, 6 seas Beye SUIS 120
|
||
awk3. 9, 17,27, 31, 33, 35, 41-42, 44, 96, 120
|
||
|
||
description... ...........20-. 88
|
||
|
||
B
|
||
|
||
D-treeWndeNng 6 sss 6 wo vores
|
||
Backups sveisis gy 6 MRS Bz ET HeH aa
|
||
balance... . 2.2.2... cee eee eee
|
||
balancesheet «ss cscs 6 so ain a
|
||
Css 4 hE 6
|
||
|
||
behead table. . .
|
||
bibliography. . .
|
||
bill of materials 3
|
||
binary data base
|
||
binary searching
|
||
DIAMK 525536 $8 Eee ss
|
||
|
||
command... wee aes
|
||
Blank ATW «sb cass se owes ass
|
||
blank row
|
||
|
||
EUS ang vo os savas X MS HERS Eo
|
||
blankinga record. ..............
|
||
DOM: 2.906 6 BGS TS Gachedayaed @ © «
|
||
Borland International ............
|
||
Bourne shell. s siecss 6 3.5 cewek se KS
|
||
Boyer-Moore search algorithm
|
||
DIOR COME Jcoccreise we 6 of Gees Sem Be
|
||
|
||
c
|
||
|
||
Gas srecsee % 5 BITE Sw EH aWENE BS 4,6,15
|
||
|
||
POinters!. | ev6.6 ee creeps se we 137
|
||
QUAN BUA, «viene & eh ners wo 8 121, 135
|
||
|
||
wiract™ BW awe @ Bi w dE Sw SH oN 295
|
||
ealepay:: 6 5 HS Ge EE Reie ee ow ane 180
|
||
RAI es cerawas ©) i KUKIEE & © & BESS 180
|
||
calculate tax form 180
|
||
CAP 86 6 KS SSE Ge ee eee 180
|
||
capitalize text 180
|
||
CASE.... 8, 22
|
||
CASE. SS Fes oe oe 9, 98, 139, 201, 247
|
||
CASH MOWs. ciecers 6 a ® erase eS BT RHEIN 181
|
||
Cashflow s cis 4 6.0 MBAS EEEES 181
|
||
Cates 5 FE bles 88, 97, 101, 105, 143, 206
|
||
|
||
==== PDF-Seite 339 / Buchseite 329 ====
|
||
/rdb Relational DBMS 329
|
||
|
||
CHAMINE so as sc anereia ew wo Kee ew
|
||
chartdup......
|
||
check.rdb. .....
|
||
|
||
COHERENT environment ...........- 3
|
||
COHERENT file system ..........-- 6
|
||
COHware
|
||
|
||
Colputh() < 2 ib aseesin a et sarees
|
||
eColputr(), sos sb 5:58.39 & © oo one
|
||
|
||
add to table. .
|
||
append row number. . .
|
||
RAERINIOHC!.. ow oicone we im 9 enevece ip 6 oe
|
||
|
||
command . 12, 16-17, 25, 28, 81, 93, 95-96
|
||
|
||
compute subtotal ............. 286
|
||
count .. 2. ee ee ete ee ee 184
|
||
find precision. .)< 35 4 6 & seas 3 & ae 255
|
||
find widest entry. 2... 6 oe ee ee es 326
|
||
find widest rows ............4-- 326
|
||
|
||
MUMVET oars bok GaKeMKae © % & aK 203
|
||
position & 66855 6 6.5 FF SR-S SE EK 203
|
||
print maximum width........... 326
|
||
TOCOMIPUtE oes 6 Ho wiwree 6 FB Gres 190
|
||
|
||
CUFSOF 6 i ee ee 98-99
|
||
|
||
GBASE to: /tdb:. «ae ausvsvs @ oe wesw
|
||
Gifference cays 4s 6 CWSI ESS SSS
|
||
SHEET. eo ose fe SS eKRER Ee me
|
||
TABIACHORS vais 6 3 ie HaDSEAI RE ow sents
|
||
find path .
|
||
gregorian
|
||
input....
|
||
intersects: 62655 6 6 § HOSS SEF Hees
|
||
NOUTERENOS cones a ¥ & erisnere® 8 © .
|
||
flan: & cuss a a 8 SRE eS oH ORES
|
||
|
||
Histiall s cnsia 4% 8 sala we EE HiBIES
|
||
|
||
MSHOSE, oi aed 3 & & Haya o © EH Risin as
|
||
HAHOtADE «:00)6 & Fo cies & = 8 Ow KGENES
|
||
MANY) 6 iain @ 6 2 woe
|
||
miscellaneous ... .
|
||
QUEBUES, wiciese 6 6 Her
|
||
printsummary.....
|
||
print syntax.......
|
||
QUOUINE: cee ee ee
|
||
FOPIACES arate <8 FIRS 428s siaEE
|
||
|
||
select .. 3 ons
|
||
BOWECHE io ose ee ieee te 2 os sivexeiiele
|
||
SOMANNCE 55 6s Kyser aw ee OOD se
|
||
show /rdb commands.
|
||
Sorttable.. ... . ) neue se ee
|
||
|
||
Siibtetalesc:: 2s saws a so a eS
|
||
SYMAK Gos GSE SWIG SEE OSS
|
||
THDICIGIA CE! ow erence 2 2 8 cae
|
||
tabletolist; . 6s secu os vw aa
|
||
tabletorule 5 < & sie7eii 5 4 BEES
|
||
tabletostruct
|
||
tabletotbl
|
||
|
||
total. .
|
||
|
||
trim ...
|
||
|
||
union ..
|
||
|
||
tipdateiie.s 6 sk soeieus 2 Re ee
|
||
|
||
Validate sais 2s 6 wexe
|
||
COMMANGS 14 3 56 aise WB H EHECTIAS &
|
||
complex queries & joins ............ 82
|
||
compress table
|
||
COMPRESAR cn a acsres © 8 87 [se
|
||
compute 'e.% 5 6 § 85 95-96, 190, 200, 202
|
||
|
||
COMMANG:. 6 6 ier0:0 m5 HS 27, 33, 43, 88
|
||
compute cash flow . . a esante 181
|
||
computedate...... 195
|
||
COMPUT FOTMIAt: ieee «ce KKM OO 115
|
||
concatenate tables .............. 309
|
||
consolidate... .........022000- 195
|
||
consolidate journals ............. 195
|
||
COMUHNUC 2. ee ee ee 166, 200
|
||
convert integer to ASCI].........-.4- 186
|
||
convert list to'shell..:. 6 6 8 sce ewes 239
|
||
convert list to ‘tables: 3 8 & tists ae 8 oS 240
|
||
|
||
==== PDF-Seite 340 / Buchseite 330 ====
|
||
330 /rdb Relational DBMS
|
||
|
||
convert name to soundex.......... 239
|
||
convert string to lowercase. ........ 243
|
||
convert string to uppercase. ........ 315
|
||
convert table format ............. 216
|
||
convert table to PROLOG facts ....... 288
|
||
copy directory
|
||
copy file... 2... . ee ee ee eee
|
||
core
|
||
|
||
CPO on :1 & © w sexenene @ Mm 8 cueNeS OBB oe
|
||
|
||
DINALY, sires is ov 6 scene eB RHE 127
|
||
delete problems ............... 78
|
||
GRID coin ooo steno a ww aMeO KW 73
|
||
entity-relationship............. 127
|
||
hierarchical. .......
|
||
infological.........
|
||
|
||
insert problems .. .
|
||
network........ © 3} ety
|
||
PFINt SCHEMA’. « o sue & wo srers
|
||
PROLOGw i trs i posites 3 HES
|
||
redundancy problems
|
||
FEIAUONA) 6. oo, steccesbra & Gi aHenwHee VS
|
||
semantic network .............
|
||
update problems. ..............
|
||
data base, relational . .
|
||
data dictionary .....
|
||
data editing
|
||
GALA ENETY: og ss ciseran ic 6 a Hae we
|
||
multi-user.
|
||
datastreaam...... wits
|
||
Datatype. «5 5 was is ow 6 EIR SKE
|
||
|
||
datatype ................-040. i
|
||
date
|
||
|
||
arithmetic
|
||
|
||
INDEX
|
||
|
||
CONVERSION ae 6 6 ee we ew SD
|
||
CONVErt! Freie os ws
|
||
European format. . .
|
||
fOrMAtS: sivcva es ws
|
||
get today .
|
||
|
||
regorian......
|
||
DUAN sesivs a i a ewes % SA G6
|
||
|
||
GDAICE. 5. cisxee co) maureen WoaeCeiEs
|
||
debugging
|
||
Default srk 8 5 eee Ss oo oe
|
||
define file .
|
||
delete...
|
||
delete row
|
||
Cs a
|
||
|
||
duplicate name
|
||
Cheek for: s avis a 4 & x0re4 a we Se 184
|
||
|
||
OF ergs we a mae Bee Same ER Ba 89
|
||
|
||
entity-relationshipo data base . .
|
||
environmental variable. ......
|
||
|
||
GXDIOKE's, ere aie ew & siucaes we BANE
|
||
explode part into subparts..........
|
||
|
||
BERET Ge es encserce oe eae & We 91 ERLEWINE
|
||
|
||
==== PDF-Seite 341 / Buchseite 331 ====
|
||
/rdb Relational DBMS 331
|
||
|
||
fast-access methods
|
||
|
||
fifth-generation language
|
||
|
||
first normal form. .......-
|
||
ee normalization
|
||
|
||
form, screen
|
||
forms editor
|
||
|
||
fourth-generation language
|
||
fourth-generation system
|
||
|
||
functional dependency PIliiiiiieg
|
||
|
||
general ledger
|
||
|
||
Gregorian a 2 ie Sie Bi MMU SSL oNReLLTeINS
|
||
|
||
hash-key indexing . .
|
||
hash-table indexing. .
|
||
hash-table searching
|
||
|
||
remove. . .
|
||
header file . .
|
||
headoff
|
||
headon
|
||
help message, print..............
|
||
helpme sis ss 5 b56s 6 EE OS BS
|
||
hierarchical data base
|
||
Hhowmany. . 2s swe es wee
|
||
|
||
I
|
||
87, 96
|
||
vie eS 9
|
||
201, 225
|
||
waereens i 2 225
|
||
SRE OT 103
|
||
CRS & 225
|
||
egestas 225
|
||
Bieter we 225
|
||
OVEN © 225
|
||
exexece wie 225
|
||
eNela Me 299
|
||
indexed-sequential searching. ....... 108
|
||
INdeXING «0 + oe eee s +. 20, 103
|
||
analyzing methods. ............ 109
|
||
tC! oc ie wo Scien ss 8 RTE ees 109
|
||
WAS HCY: oo a eceerew © a Sucare 8 222
|
||
infologicaldata base ........-..-- 127
|
||
information
|
||
grand unified theory
|
||
insertdash..........--
|
||
installing /rdb. .. wee ee eee eee
|
||
integer
|
||
convert to ASCII ......
|
||
integrated software... . .
|
||
intersect 6 6 6 eerece @ @
|
||
command..........
|
||
intersection of tables
|
||
inventory oc 6 6 oe csrsns ws
|
||
updates. i 5 § & HiRes se
|
||
inverted indexing.......
|
||
INVOKC esac GE Kaan & s
|
||
ipdigitt)s.5..< 5 2 Dare & EE RRS RE
|
||
J
|
||
JO «aia ae sw we see @ © 6 Bet oo «
|
||
command
|
||
join tables ...........
|
||
|
||
join, pipeline
|
||
joining tables
|
||
jointable ...
|
||
JOU Halse a eb ceases wet maT & a
|
||
|
||
consolidate.........
|
||
|
||
manipulate .
|
||
julian.....
|
||
|
||
command .
|
||
Julian date. . .
|
||
Julian dates. .
|
||
|
||
justlfys.c.s.¢ ess os
|
||
|
||
INDEX
|
||
|
||
==== PDF-Seite 342 / Buchseite 332 ====
|
||
332 /rdb Relational DBMS
|
||
|
||
JUstify COMME « 5. erences 2 ee mimes © 2 234
|
||
K
|
||
Key column 6.066 cee eo eels e PEK
|
||
Knuth, Donald... .........4% 239, 283
|
||
Kornishell ae 6 cwesea a a x meee 27, 83
|
||
FBR siecle F 6 aMalislS fe & alaliaiicie 27, 88
|
||
L
|
||
labely ss 3 a 55 botwirsrnd & & & Sevan & ® 236
|
||
language, fourth generation. . . ov 4
|
||
language, third generation........... 4
|
||
ledger
|
||
ClOSG sw xe mieieena ew eh MEO ee 187
|
||
length... wc scree eee see werece 237
|
||
length of string «0.0.6. ee eee sees 237
|
||
5 re keer oc ey 237
|
||
lettera sprints § wajeseyi sk GE HRA SSS 237
|
||
BEAD a. icc oo arenes & ww Of eheciorD ew 8 154
|
||
Le Ce er ce eo eo ee 239
|
||
DIS .tu © » fe pumesees nS seeneue a nF 4
|
||
list
|
||
check tf file 16.) :i0s00a 6 & 2 4 eases Be 288
|
||
convert from table..........+.-. 290
|
||
Convert to shell... 6 oo esse 6 oe 239
|
||
Convert to tables icici. 6 6 60 cies ewe 240
|
||
definition i eevee ects sees 14
|
||
list allcommands........0e+ eee 257
|
||
list commands
|
||
Hat format © é & biwieie 35 EE cts TRE HS
|
||
UBCIOSB: . 6 w w wrerice 6 oom BrevUe 6
|
||
listtotable
|
||
In.
|
||
lock
|
||
lock table while editing........ see 323
|
||
locking records «0... esse eeeevee 111
|
||
NORD 6 eae & secouwie © W i ae. Sw OS 107
|
||
logical NOT. «. ii6 ses 6 ob elie Swe os 249
|
||
TOWEICABE 6 oo esieeneie em 9 omesexe a ALS 243
|
||
ID ois bs 6 ee IERIE WS & sileite 20, 135, 201
|
||
M
|
||
M45 5.5 6.0 TON SOF S .
|
||
machine instructions. ............+.
|
||
MAGINtOBR 3: wcoesiis @ 0 et aaa 6 ww ateia
|
||
Mailing list. 6.3666 6 6 eae ele So 8 bles
|
||
TOBIN). ow wrewece 9 2 wo ereieiere 2 wm ens
|
||
MARC 6 6 oo siaens 6 Sw SarEKEOS ow Bee
|
||
Makefile: «6 sie 6 6 6S bseie se 8
|
||
AMATI: 6: sicsiornone te 8 9 wietMEeie oe KARE
|
||
MAUOCO s,s: § a:a5675. Fe KHER
|
||
manipulate journals ...........0.
|
||
|
||
many-to-many relationship. . .
|
||
many-to-one relationship . .
|
||
|
||
match
|
||
partial initial ... 109
|
||
Mathemancesiccis 2s F HRS A ES ENS 125
|
||
|
||
INDEX
|
||
|
||
MS-DOS.
|
||
multi-user access to files .........- 119
|
||
multi-user dataentry...........5085 40
|
||
|
||
name, convert to soundex.......... 239
|
||
network data base .........-+005 126
|
||
nonprocedural statements........... 87
|
||
normal form
|
||
|
||
fe]
|
||
Odi oF 8 eeere 4 oF See x gE Pa 43, 88
|
||
one-to-one relationship ........++++. 73
|
||
CHEWY PINS. 05:6 seo 0 rece 6 & & SKiOSe 140
|
||
ODEN Ie aw sverers ww setae we wR eee 151
|
||
operations: (76. 5 i 5 i eles 8 OK EF SORES 170
|
||
P
|
||
PACK oo neon 2 © sCMOUR & & aLOENERe 202
|
||
PAG a sc piarass 2 2 & BEE. Kw WR aTRT 251
|
||
padstring. 6.50 ese cree tvens 252
|
||
paradigm, buddy canyou........... 7
|
||
Parsing rows es sso Swiss ss E HID 91
|
||
partial initial match ............+. 109
|
||
PASCAL. 9: worsen a & marEse aw & H BHOZEREN 8
|
||
paste tables
|
||
paste.rdb.....
|
||
path. .
|
||
payroll .....
|
||
calculate . . ‘ .
|
||
DAs & 4 Weiss 6 EE WOR BE GE ote 4s
|
||
|
||
==== PDF-Seite 343 / Buchseite 333 ====
|
||
/rdb Relational DBMS 333
|
||
|
||
POTTOF() once ee ene ee dae 152-153
|
||
|
||
DIPS «. vxevexs 8, 13, 31, 104, 140
|
||
one way cee 140
|
||
to standard input 141
|
||
two-way
|
||
|
||
pipe key
|
||
|
||
pipe() ......-
|
||
pipeline join . .
|
||
PUSL e-6:0,38-%
|
||
|
||
planning...
|
||
post payroll
|
||
|),
|
||
precision.........-.
|
||
predicate calculus ....
|
||
print invoice........ 48 a6
|
||
PCIE Tethers ye eo cseiece ese bs ecenerie ss
|
||
print mailing labels. .........-+5+- 236
|
||
procedural programs. .......+++++- 87
|
||
program
|
||
POStciewe 6 a ww abe w SH sHaMENELS 299
|
||
time execution... 6.6.5 eee eevee 299
|
||
programming style .......-++++++ 146
|
||
Project sss ee we ee we eee 256
|
||
command 2 eee 126
|
||
PROLOG 60630356 6 <0 9 ae
|
||
convert table to facts . . 288
|
||
|
||
convert table to rules . .
|
||
|
||
facts. cieiecs ee were
|
||
|
||
problems .
|
||
|
||
questions .
|
||
|
||
TUNES 6. 0:6:5
|
||
|
||
tabletofact.
|
||
|
||
tabletorule
|
||
prompt....
|
||
purchasing.
|
||
puts().. ee eee cere eer eens
|
||
|
||
3
|
||
quotation mark .. 2.1... eee eee 31
|
||
quotation marks ..........++4+ 31,43
|
||
quoting commands. .......++++++5 31
|
||
R
|
||
|
||
PUD 6: Erase FFE RT ww Oe 257
|
||
TOD: ooo eco ie co ces 8 6 8 HH eee 157
|
||
bs Oe « 90, 92, 98, 101, 200, 202, 247
|
||
read (). scisisies & 6 & HHO 140-141, 149, 151
|
||
TOCOTG. 6 eee ie oe qumeee ie ss & eybses se 257
|
||
|
||
blanking... 5 5 oe sysce:9 oo © veces 112
|
||
|
||
convert to fixed-length .......... 289
|
||
|
||
UPdAte o-oo eo 8 opecers eso egies 312
|
||
record locking........ 111, 242, 310, 323
|
||
record searching .........e00008 106
|
||
TOFETENCES 0. 0 2 oo creere ee 8 econ #8 22
|
||
OMIBER ie scsiisie Se FS Saws fe Sw BESTE 144
|
||
relational data base. . . . - 2,11, 126
|
||
relational model... »: viec0:. 6 6 6 wes 8 © 2
|
||
relationship
|
||
|
||
many-to-many.............2+4. 74
|
||
many-to-one
|
||
one-to-one ....
|
||
remove core files . .
|
||
FeMOve HEAMET.. w:0.c0: eww epee ee 8
|
||
TOHAMG ec ow ateoes Tl ee
|
||
reorder columns
|
||
TEPIACE a). 0 cw wiiciene wee
|
||
Command ss esis es 6 wisiwiere we oi «
|
||
|
||
po
|
||
|
||
report template
|
||
|
||
report writing . 2.2... ese enees
|
||
|
||
TEpOrts 2. 2 ce sere
|
||
|
||
reportwriter .....
|
||
|
||
reposition cursor . . cree
|
||
|
||
FOCUS 0:46 6 oe aioe ew ye eee ww
|
||
|
||
return value
|
||
WELT seis once mone 2 ee Hy SS 249
|
||
|
||
Feturn() 02 se ewe 152
|
||
|
||
rmblank 2.3 6 i 0% 264
|
||
|
||
TINCOTE cee eo ecese 266
|
||
|
||
append <5. ies 209
|
||
append to table. . . a sere o« 42
|
||
BANK OU. co cswie ss SA We KERR, & Ho 177
|
||
command... .
|
||
GENS ack so: aseiess wo & 6 Kacoens Ses
|
||
|
||
find quickly. ....
|
||
find r. by number .
|
||
number column . .
|
||
|
||
replace........
|
||
select by expression aes
|
||
select via expression............ 266
|
||
RPG seacsva ce 0 & wwieie so Se CLEKMIMS BRHF 6
|
||
|
||
scat... eae
|
||
Schemas: ic 4 sweewes 8 TK Baterses wo
|
||
|
||
FOB coo siemens 2 2 = eee SHES
|
||
|
||
Bild. 6.5, wens
|
||
screen template. . suena sae
|
||
BCHPbres sso wees eH EE Sw 6D HB
|
||
|
||
==== PDF-Seite 344 / Buchseite 334 ====
|
||
334 /rdb Relational DBMS
|
||
|
||
BORK ones 2 ee w wEEErEw 103-104, 201, 273
|
||
Binary ass 6 EH SL EE RECON Fe 274
|
||
COMMA. 6 6 6: cresers ie 0 © ewecere ee 149
|
||
ASR asis6 oo & ouarare se we BreRECaD 274
|
||
indemed 5 is 6 8 sO F FE ESCO eS 275
|
||
TRVOPEOR «oo 6: 9, connie oe & sewn #8 275
|
||
UNO OS cia i we ws OHeeES FE WiMRON 275
|
||
POCONG 655 5-5 Fi eens EE Kates TS 275
|
||
MeGuUERntAL, «ao ween 6 a © HOKE 274-275
|
||
CORE ries % FH Payee oF K MUO BS 299
|
||
|
||
searching
|
||
DINATY es eo ew RNaHOM % w & CILAENE WIS 106
|
||
hash table; ¢ 6 c4isien & 6 ¥ REO Fo 107
|
||
indexed sequential............. 108
|
||
Hrverted ss ss ceca «ew wuasestie 6 %
|
||
POCOR 55.8 FF if aieiies 6 ow Sarees & 5
|
||
POAUOTIAL, oo ocesvecerne 1% 9) Guemennee ee
|
||
|
||
searchtree ......
|
||
|
||
second normal form
|
||
|
||
security. ...... l
|
||
|
||
sed... 3, 17,35, 41, 88, 96, 200, 227, 294
|
||
|
||
BOS 5551655 Male Fi RAS 8 HE NSA GBF
|
||
COMMA. wiecerese 2 2: opeuece ne ©
|
||
|
||
ORR ac aw se wares aa
|
||
|
||
BORK) is 6 F&F REGOH AE HGS
|
||
|
||
Peace ce aww sreuniens Ko S AY
|
||
|
||
select COlIMNSS. ssvcisic. 2 ss Sess % eee 18
|
||
|
||
selected commands. ........+++005
|
||
|
||
semantic-network data base ........ 127
|
||
|
||
WOIMANEICS: i x i excciewes 0 i RUE ee LG 32
|
||
|
||
sequential searching...........+: 106
|
||
|
||
BOG eves a so esenennes @ & & raEENe & 91,203
|
||
|
||
BOs ane ww oo BrETERNE eH 6 CERNE @ 88, 137
|
||
|
||
Shes os ss 6 Fe HENS 8 GE HOON BT EHS 5
|
||
BOUrRe: es vise ies © & Sere ee 8 ee 83
|
||
KOM. aos 6 v sucoraw one BEG we EN 83
|
||
trace option: ©. ee vee cece 92
|
||
|
||
BO ERIS oo: serene is wee OHSS «woe 97
|
||
|
||
shell + ees 3423S oO ROA WES Ee 87
|
||
definition . . = ©5688 Dee ee us 13
|
||
|
||
@hell scripts: . soscenes oom wawrew ¥ . 33
|
||
|
||
shell, definition . or . 8
|
||
|
||
shift. ...... - 91
|
||
|
||
size of table ascae BS
|
||
|
||
sizeofl) . 0 5 SM OH Se 141
|
||
|
||
BOLE ss Sh Fesere se ae one 5, 42, 205, 227
|
||
|
||
sorttable 18, 83, 95-96, 281
|
||
commana «64s 4 8 HH % 13, 36, 76
|
||
|
||
SOUNGEK 6 bb bases so eo prewone 2 s 239, 283
|
||
|
||
special characters... 0 0. see eee one 43
|
||
|
||
Spells o.5 se es FE eS TO SE 5, 89
|
||
|
||
aplittable:: & 6 fui. 8 2 8 8 ee acases eo 8 os 284
|
||
|
||
BPTINGY. 6 6 wwe 6 ow & HeSeROI ew BRYON 96
|
||
|
||
SQlis 6 sé 6 Vises oy EROS To 21, 126
|
||
|
||
Standard Sr7OFs..0. 66 oe eececere 9 0 © oe 158
|
||
|
||
standardinput ....... 15, 141, 143, 206
|
||
|
||
standard output........... 15, 83, 206
|
||
|
||
BEALL so wo: cries as wt meNeKonn® i 151,215
|
||
|
||
Static CHAT asians 6 as RE ae HES 157
|
||
|
||
gtderrs 6&5 E656 & SE ce 142, 144, 147, 158
|
||
|
||
Sti, Asa ae ss eceveraa 2 oe 8 EER Ss 147, 164
|
||
stdoutes is 5 Heche FE OG WO GS Ee 147
|
||
BIER « 2 oe cieee 2 ee mae ee ewe 7-8
|
||
string
|
||
convert to lowercase ........... 243
|
||
convert tosoundex ...........- 283
|
||
convert to uppercase ........... 315
|
||
len; boule # 8 em etd da =
|
||
pad with spaces ...........-4-
|
||
Prompt 2. ees cede sence 256
|
||
FODIACE. oo. cores woo erwin eo Os 285
|
||
trim white space... .. 6... 0005 307
|
||
etrlenl) i ss Gaels 3 8 EE eee BG ORS 145
|
||
BUCO wee ee eyeieie ee 8 eee 150, 295
|
||
|
||
tab
|
||
column separator .............. 42
|
||
|
||
TAD Bass oo nese wo ana wa wo ee A ll
|
||
GOR. 5 i 5 Wiss bd 4 WSN GE SS eS 300
|
||
addhead ...........000 000s 223
|
||
BAG TOW savers ee ww eianane 6 we we RLORD 209
|
||
append Tow ss 6 sk ew aiew Be es 172, 209
|
||
append row-numbercolumn....... 249
|
||
DeMeAds: sissy cm 6 samnennns ve ww «oar
|
||
check if file is te
|
||
compress ...
|
||
compute tax .
|
||
concatenate......
|
||
convert format
|
||
convert to C struct.
|
||
convert to fixed-length .......... 289
|
||
Convert to list. 6. csieeie o 6 ew wiene 290
|
||
converttom4...........4, 291,310
|
||
convert to PROLOG facts......... 288
|
||
convert to PROLOG rules......... 292
|
||
convert tosedcommands ........ 294
|
||
converttotbl..........000005 296
|
||
CREAIE! orepoie 2 a 0 & HiOLMNE Cw WB OeMEOw 17
|
||
Create new 4 4 i 6 i Wwe & % TE WSO 266
|
||
difference... .. eee eee eee 205
|
||
OMG cress 6 ee aan 6 9 No oreKe 318
|
||
|
||
WOde art: 5 ey Heise & ¥ EF EOS 212
|
||
|
||
find intersection. ............4. 117
|
||
fited length. ie xo wieiainn a ee screen’ 216
|
||
from istics 6 6 6 essences 2 © 0: ejecevens 240
|
||
WAGE cesses we ow aielieren @ % @ a! nveTRNON 225
|
||
|
||
==== PDF-Seite 345 / Buchseite 335 ====
|
||
/rdb Relational DBMS 335
|
||
|
||
insert dash line: «3 6 vac so 6 ee 227
|
||
WIETHECE) coneice ns euers FSH SAO
|
||
|
||
join two t. . a ae
|
||
faathy. saws ea Ses
|
||
|
||
print schema... 6 6 6 ssw so 8 eles 270
|
||
rules for creation. . 2... 00sec eee ee ll
|
||
rules for making
|
||
GIZEs Fb EG 6 6 & HTT Sw HEH.
|
||
|
||
SPE 6 s wavevene « « © 018
|
||
split horizontally sae %
|
||
subtotal oo. ess ss syeietes © 8 eae
|
||
SUDHACEs; beiece oe eo wren wes
|
||
|
||
trim white space
|
||
MOOG, o:eresexe ox 2 qrexecum © FS TPs
|
||
|
||
table format .. 2... eee ee ee ee
|
||
table Width, weve. aa 6 meveans eo © saree
|
||
table, definition
|
||
tableorlist .. .
|
||
tables and forms ......
|
||
tabletofact 5 6250.5 5 5 5 Seer ees
|
||
tabletofix. .. .
|
||
tabletolist. . . .
|
||
tabletom4 ...
|
||
tabletorule. . .
|
||
tabletosed .. .
|
||
tabletostruct. .
|
||
command. .
|
||
tabletotbl. . . .
|
||
|
||
TAKS oo we 6 cies so & pew © 8 De 296
|
||
|
||
CEE oo ec ereee ee te mewn 6 ee mee
|
||
|
||
TAG. oo & <; wivecee = se Nigam © Se sre
|
||
REPMCAP., 6. i: seers 6 68 terezens
|
||
|
||
find entry forTERM...........-. 307
|
||
terminal
|
||
|
||
get capability ei. i 6s sevens 6 6 6 ease 297
|
||
terminology: 20. 66 8 2b tielerels Fao ee 125
|
||
TELMPUE.. « ereievere oe 9 enero we © 99, 297
|
||
TEOt 6 6 68 crores we & WEEONS we w ON 9, 92
|
||
test functional dependency ......... 214
|
||
TOMA sw 9: syeierew © © © enwimmde mH estesis 299
|
||
TOSTHOAICH: seecescw a a & Beat wae TORI 299
|
||
text
|
||
|
||
CAPITAN cere se 9 0: : srreveie ie ow im exe
|
||
|
||
find unique words
|
||
|
||
translate..........
|
||
|
||
third normal form
|
||
|
||
third-generation language. .......... 4
|
||
time execution... 2.2.2.6 cee wees 299
|
||
timesearch
|
||
todaysdate
|
||
total......
|
||
|
||
transitive dependencies . oe
|
||
translate ..66 6 6 eee eB ie 301
|
||
tree
|
||
BEATCH a8 26 6 ween ce & & 6) w) srmrenants
|
||
|
||
trims sees. 6 KE ES
|
||
|
||
trimblank.
|
||
troffs 6 «xs
|
||
tset 2 ces
|
||
two-way pipe
|
||
type of data
|
||
|
||
command.......
|
||
uniondict.........
|
||
WTIG.«. 0. osecee ce eo gene
|
||
universal relation. . . ene
|
||
UNIX Worl 2 se sleleis 656 Laversliens.%
|
||
TURMOCKE: ee uecene se
|
||
WPGAlO: & ccoigns 4s Wareuermae w @
|
||
update inventory ....
|
||
update table.......
|
||
update.inv........
|
||
update.rdb........
|
||
uppercase ........
|
||
US format ........
|
||
UBtAL: 6 sis 8 FS eS SK SF eTIC 120
|
||
|
||
NEUGELC scone & § FIEND 88, 317, 43-44, 120
|
||
validate datains io series 6 9 6 fH rerary, 120
|
||
validate table ..........2055 207, 323
|
||
ve 12,14, 17, 35, 39, 101, 119-120, 200, 318
|
||
Verify COMMM|S 6 <.56 4 6°8:0.6.46 0.5 Sauetels 184
|
||
vi
|
||
|
||
WO. we ewer ee enews
|
||
|
||
wheel, reinvent
|
||
WHI: saiciwis 4 eB BE
|
||
while().. 2... eee ee
|
||
white space
|
||
|
||
INDEX
|
||
|
||
==== PDF-Seite 346 / Buchseite 336 ====
|
||
336 /rdb Relational DBMS
|
||
|
||
trim from string .............. 307
|
||
|
||
trim from table... .........0058 302
|
||
WIEBE oreine see & 2 oeB RTOS 8 E STKERD Ie 326
|
||
WERE ocras se a a 3) evateere ww we HELENE @ 326
|
||
Winston, Alans § s ésiies & Fo HR HS 94
|
||
WORD vocescoics 2 wo of onenexe ie 2 ow enesere ls 326
|
||
WEEE TUE iiss e so 5 cise s Hg eeDE
|
||
WHOS sisi 4s bE ARTE 141-142, 145, 149
|
||
| ai mirarorars @ 6 ot Mamas Ya eS 13, 17, 26, 31
|
||
|
||
INDEX
|