Rdb: Ruby-Nachbau der MWC /rdb-Werkzeuge
This commit is contained in:
+364
@@ -0,0 +1,364 @@
|
||||
.TH compute "" "" "/rdb Command"
|
||||
.PC "Calculate columns of a table"
|
||||
\fBcompute '\fIcolumn \fB= \fIexpression \fB[ ; ... ]' < \fItableorlist\fR
|
||||
.PP
|
||||
.II "arithmetic^column"
|
||||
.II "column^arithmetic"
|
||||
.II "column^recompute"
|
||||
The command
|
||||
.B compute
|
||||
lets you to do arithmetic on columns.
|
||||
A column can be computed as a function of other columns, of itself,
|
||||
and of constants.
|
||||
.PP
|
||||
.B compute
|
||||
uses the COHERENT command
|
||||
.B awk
|
||||
to perform its work, as
|
||||
does the command
|
||||
.BR row .
|
||||
.B awk
|
||||
is a a powerful, interpreted programming language in which you can write
|
||||
programs to perform complex transformations on text.
|
||||
The advantage of
|
||||
.B compute,
|
||||
over
|
||||
.B awk
|
||||
is that
|
||||
.B compute
|
||||
knows about the names of columns in a table;
|
||||
this permits you to use column names instead of column positional numbers.
|
||||
(In
|
||||
.B awk
|
||||
the second column is named
|
||||
.BR $2 .)
|
||||
To grasp the full power of
|
||||
.B compute
|
||||
and
|
||||
.BR row ,
|
||||
read the COHERENT system's
|
||||
.B awk
|
||||
tutorial.
|
||||
If you must perform very complex manipulations of tables, use
|
||||
.BR awk .
|
||||
.PP
|
||||
If you must create a new empty column for
|
||||
.B compute
|
||||
to put values into, use the command
|
||||
.BR column .
|
||||
This command
|
||||
creates an empty column for any
|
||||
column it cannot find in the header line.
|
||||
.SH Example
|
||||
This example computes a column from other columns:
|
||||
.DM
|
||||
compute 'Value = sprintf("%5.2f", Cost * Amount)' < inventory
|
||||
.DE
|
||||
.DM
|
||||
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
|
||||
.DE
|
||||
.PP
|
||||
Here are more examples of what you can do with compute.
|
||||
You can change the format of \fBcolumn\fR by using a C-style
|
||||
.BR sprintf :
|
||||
.DM
|
||||
compute 'column = sprintf ("%8.2f", column)' < tableorlist
|
||||
.DE
|
||||
.PP
|
||||
You can
|
||||
set \fBcolumn\fR equal to the length of the string in \fBcolumn2\fR:
|
||||
.DM
|
||||
compute 'column = length (column2)' < tableorlist
|
||||
.DE
|
||||
.PP
|
||||
You can also
|
||||
Set \fBcolumn\fR equal to the natural logarithm of \fBcolumn2\fR:
|
||||
.DM
|
||||
compute 'column = sprintf("%f", log (column2))' < tableorlist
|
||||
.DE
|
||||
.PP
|
||||
Or, you can
|
||||
increment \fBcolumn2\fR whenever \fBcolumn\fR is greater than \fBnumber\fR:
|
||||
.DM
|
||||
compute 'if (column > number) column2 = \e
|
||||
sprintf("%d", column2+1)' < tableorlist
|
||||
.DE
|
||||
.SH Expressions
|
||||
As you can see, you can write rather complex expressions for
|
||||
.BR compute .
|
||||
By
|
||||
.I 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:
|
||||
.IP \fBcolumn\fR 0.3i
|
||||
Name of a column, exactly as it appears at the top of the column.
|
||||
.IP \fB\(eq\fR
|
||||
Make the column on the left equal the expression on the right.
|
||||
.IP \fB+\fR
|
||||
Add
|
||||
.IP \fB\-\fR
|
||||
Subtract
|
||||
.IP \fB*\fR
|
||||
Multiply
|
||||
.IP \fB/\fR
|
||||
Divide.
|
||||
.IP \fB%\fR
|
||||
Modulo (zero if left value is equally divisible by right).
|
||||
.IP \fB;\fR
|
||||
Statement separator needed if more than one equation
|
||||
.IP \fBlog()\fR
|
||||
Natural logarithm of value or column within parentheses.
|
||||
.IP \fBlength()\fR
|
||||
String length of string in column.
|
||||
.PP
|
||||
You can also use C language-like statements:
|
||||
.IP "\fBif (\fIexpression\^\fB) \fIequation\fB [ else \fIequation\fB ];\fR"
|
||||
For example:
|
||||
.DM
|
||||
if (Value > 10000) Status = "Special"; else Status = "Normal";
|
||||
.DE
|
||||
.IP "\fBwhile (\fIexpression\fB) \fIequation\fB;\fR
|
||||
For example:
|
||||
.DM
|
||||
while (column => 0) column -= 1 ;
|
||||
.DE
|
||||
.IP "\fBfor (\fIexpression\fB; \fIcondition\fB; \fIexpression\fB) \fIequation\fB;\fR"
|
||||
For example:
|
||||
.DM
|
||||
for (i = 0; i < column1; i++) array [i] = column2 + i ;
|
||||
.DE
|
||||
.PP
|
||||
You can also use the
|
||||
.B awk
|
||||
format \fIpattern \fB{ \fIaction \fB}\fR.
|
||||
For example:
|
||||
.DM
|
||||
compute 'length > 80 { print NR, "Line too long." }' < table
|
||||
.DE
|
||||
.PP
|
||||
.B awk
|
||||
recognizes
|
||||
.I length
|
||||
as a function that returns the length of the row and
|
||||
.B 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).
|
||||
.SH "What Is a Column Name?"
|
||||
.B 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,
|
||||
.B 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
|
||||
.BR awk .
|
||||
.PP
|
||||
.B compute
|
||||
defines a column name to be a string of the following characters:
|
||||
.IP \fB1.\fR 0.3i
|
||||
Upper and lower letters, numbers, and the underscore `_'.
|
||||
.IP \fB2.\fR
|
||||
Any string that is enclosed by apostrophes or quotation marks.
|
||||
.PP
|
||||
Therefore, if you want special characters in your column names,
|
||||
put quotation marks around them when you use them.
|
||||
For example:
|
||||
.DM
|
||||
compute ' "Item#" = NR ' < inventory
|
||||
.DE
|
||||
.PP
|
||||
Note the quotation marks around the column head
|
||||
.B 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.
|
||||
.SH "Reserved Words to Avoid in Column Names"
|
||||
Some words are understood by
|
||||
.BR 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.
|
||||
.B awk
|
||||
does not confuse
|
||||
.B Print
|
||||
with
|
||||
.BR print .
|
||||
Here is a list of
|
||||
.BR awk 's
|
||||
built-in functions.
|
||||
.nf
|
||||
.sp \n(pDu
|
||||
.ta 1.6i
|
||||
\fIReserved Words Description\fR
|
||||
.tc .
|
||||
\fBBEGIN\fR Pattern that matches before first input record
|
||||
\fBEND\fR Pattern that matches after last input record
|
||||
\fBbreak\fR Get out of for or while loop
|
||||
\fBcontinue\fR Go to next iteration of for or while loop
|
||||
\fBelse\fR Used in "if then else" expression
|
||||
\fBexit\fR Leave program entirely as if end of input
|
||||
\fBexp\fR Raise number to a power
|
||||
\fBfor\fR for ( expression ; condition ; expression ) statement
|
||||
\fBgetline\fR Get next input line
|
||||
\fBif\fR if ( condition ) statement [ else statement ]
|
||||
\fBin\fR for ( variable in array ) statement
|
||||
\fBindex\fR index ( string1, string2 )
|
||||
\fBint\fR Truncate argument to integer
|
||||
\fBlength\fR Return current line length, or length of argument
|
||||
\fBlog\fR Return log (to base 2) of argument
|
||||
\fBnext\fR Skip to next record and reexecute all commands
|
||||
\fBprint\fR Output variables
|
||||
\fBprintf\fR printf ("format", variable, ... )
|
||||
\fBsplit\fR split ( string, arrayname, separator)
|
||||
\fBsprintf\fR sprintf ("format", variable, ... )
|
||||
\fBsqrt\fR Return square root of argument
|
||||
\fBsubstr\fR substr ( string, start, number )
|
||||
\fBwhile\fR while ( condition ) statement
|
||||
.tc
|
||||
.fi
|
||||
.SH "Using Shell Variables in Programs"
|
||||
Often you want to use a shell variable in a
|
||||
.B compute
|
||||
command.
|
||||
It is easy, if you understand what is going on.
|
||||
For example, the following commands:
|
||||
.DM
|
||||
DATE=860101
|
||||
compute "Date = $DATE" < journal
|
||||
.DE
|
||||
.PP
|
||||
produce the following output:
|
||||
.DM
|
||||
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
|
||||
.DE
|
||||
.PP
|
||||
We set a shell variable named
|
||||
.B DATE
|
||||
to a date.
|
||||
Then we used the variable in the
|
||||
.B 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 `$' in front of
|
||||
.B 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).
|
||||
.PP
|
||||
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
|
||||
.BR awk ,
|
||||
they must have quotation marks (not apostrophes) around them.
|
||||
For example:
|
||||
.DM
|
||||
COMPANY='Makeapile, Inc.'
|
||||
compute "Company = \e"$COMPANY\e"" < maillist
|
||||
.DE
|
||||
.PP
|
||||
produces the following:
|
||||
.DM
|
||||
.ta 1.0i
|
||||
Number 1
|
||||
Name Ronald McDonald
|
||||
Company Makeapile, Inc.
|
||||
Street 123 Mac Attack
|
||||
City Memphis
|
||||
State TENN
|
||||
ZIP 30000
|
||||
Phone (111) 222-3333
|
||||
.DE
|
||||
.DM
|
||||
.ta 1.0i
|
||||
Number 2
|
||||
Name Chikeeta Banana
|
||||
Company Makeapile, Inc.
|
||||
Street Uno Avenito De La Revolution
|
||||
City San Jose
|
||||
State El Salvadore
|
||||
ZIP 123456789
|
||||
Phone 1234
|
||||
.DE
|
||||
.PP
|
||||
Here we set a shell variable
|
||||
.B 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
|
||||
.BR awk .
|
||||
So we have to protect the innermost quotation marks with backslashes.
|
||||
.PP
|
||||
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.
|
||||
.SH "Problem With awk Floating-Point Format"
|
||||
With some implementations of
|
||||
.BR awk ,
|
||||
the value column is computed to much greater precision
|
||||
than you are likely to want.
|
||||
For example, version produces this table:
|
||||
.DM
|
||||
Item# Amount Cost Value Description
|
||||
------- ------- ------- ------- ---------------
|
||||
1 3 5.00 15 rubber gloves
|
||||
2 100 0.50 50 test tubes
|
||||
3 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
|
||||
.DE
|
||||
.PP
|
||||
To control the precision of the
|
||||
floating-point values in a column, you can use the
|
||||
.B sprintf
|
||||
function from the C programming language that has been implemented in
|
||||
.BR awk .
|
||||
For example:
|
||||
.DM
|
||||
compute 'Value = sprintf ("%7.2f", ( Cost * Amount ))' < inventory
|
||||
.DE
|
||||
.PP
|
||||
These commands will produce the first table under Examples, above.
|
||||
.SH "See Also"
|
||||
COHERENT Lexicon:
|
||||
.B
|
||||
awk,
|
||||
ksh,
|
||||
sh
|
||||
.R
|
||||
Reference in New Issue
Block a user