home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / awk / awk320.zip / AWK.DOC < prev    next >
Text File  |  1991-05-04  |  23KB  |  609 lines

  1.  
  2.                        The AWK Programming Language
  3.                          Users Manual and Tutorial
  4.  
  5.         This document is an introduction to the use of AWK for manipulating 
  6. text and the textual representation of numbers.  This mouthful means that you 
  7. can use AWK to manipulate words and numbers. 
  8.  
  9. 1.  Basic Concepts
  10.  
  11. 1.1 AWK Programs
  12.  
  13.         AWK programs consist of a series of PATTERNS and ACTIONS.  Patterns 
  14. are boolean (logical) expressions that are evaluated and if they are true 
  15. (non-zero number or non-null string) then the associated Action is performed.  
  16. Actions are program fragments in a "C" like language. 
  17.  
  18.         The Pattern-Action statements comprising an AWK program are evaluated 
  19. in turn for each input RECORD.  That is, a Record is read and the Patterns in 
  20. the program are evaluated in order, for each Pattern that succeeds, an Action 
  21. is performed.  For example:
  22.  
  23.     NR == 5 { print }
  24.  
  25. is a simple program that prints the fifth line of a file.  NR is a built-in 
  26. variable that is equal to the number of records AWK has read so far.  The 
  27. double equal sign is the equality comparison operator from C.
  28.  
  29.         As you can see from the above example, a Pattern is a naked expression 
  30. and an Action is a compound statement or list of program statements enclosed 
  31. in braces ({}).
  32.  
  33.         You may omit the Action in a Pattern/Action statement in which case 
  34. the default action is { print }.  You may, on the other hand omit the Pattern 
  35. which defaults to true, so that the Action is always taken.  Finally if you 
  36. omit both the Pattern and the Action you have a blank line, which is ignored. 
  37.    
  38. 1.2 Fields and Records
  39.  
  40.         To AWK all data are divided into FIELDS and RECORDS.  The definition 
  41. of a field is any string of characters separated by the Field Separator or FS 
  42. for short.  Similarly a record is any string of characters separated by the 
  43. Record Separator or RS.
  44.  
  45.         In the simplest form a Field is a string of characters surrounded by 
  46. white space (blanks or tabs,) and a Record is a line of text.  You can make 
  47. the Field Separator as complex as you like by providing your own REGULAR 
  48. EXPRESSION for the FS.  The Record Separator is limited to the null string "" 
  49. or a newline "\n".  The null string means that a blank line separates a multi-
  50. line record, and the newline means that each line is a record.
  51.  
  52.         You can refer to the Fields in the current Record with the dollar ($) 
  53. operator:
  54.  
  55.     $3 < 10 { print NR, $0 }
  56.  
  57. here $0 denotes the entire Record, and $3 is the third field.  If the tenth 
  58. line of the input file was:
  59.  
  60.     Rob Duff 7
  61.  
  62. the output generated for this record by the one line program would be:
  63.  
  64.     10 Rob Duff 7
  65.  
  66. since the third field (7) is less than 10 the record number (10), followed by a 
  67. space (the Output Field Separator OFS), followed by the whole record ($0).
  68.  
  69. 1.3  Regular Expressions
  70.  
  71.         You may wonder why something like NR == 5 would be called a Pattern, 
  72. well, the name comes from pattern matching with Regular Expressions.  A Regular 
  73. Expression is a formula for matching strings.  The simplest is straight 
  74. matching a string of characters within a line: 
  75.  
  76.     /with/
  77.  
  78. will match a Record that contains the substring "with" at any point.  A more 
  79. complex Regular Expression is Alternation (one string or another):
  80.  
  81.     /with|line/
  82.  
  83. which is equivalent to
  84.  
  85.     /with/ || /line/
  86.  
  87. which will match any Record that has "with" or has "line" as a substring.  A 
  88. somewhat less simple concept is the CLASS or set of characters:
  89.  
  90.     /[0-9]/
  91.  
  92. will match any digit and
  93.  
  94.     /[a-zA-Z]/
  95.  
  96. will match any upper or lower case letter.  A special Class is the period (.) 
  97. which will match any character. 
  98.  
  99.         Next we come to the repetition operators there are three of them, one 
  100. for zero or more occurances of a pattern, the asterisk (*), another for one or 
  101. more, the plus sign (+), and finally the one for zero or one occurances of a 
  102. pattern, the question mark (?).  For example the pattern:
  103.  
  104.     /[0-9]+/
  105.  
  106. will match one or more digits or in other words it will recognize numbers.
  107.  
  108.         As you can see a Regular Expression is delimited by slashes (/) in the 
  109. same fashion as a string is delimited by quotes ("). 
  110.  
  111.         You can use a Regular Expression in a pattern all by itself or in a 
  112. logical expression:
  113.  
  114.     /line/ { print "line", NR}
  115.     NR > 5 && /with/ { print NR, $0 }
  116.  
  117. or you can use the match operator tilde (~) when you want to match anything 
  118. other than the Current Record ($0):
  119.  
  120.     $2 ~ /ff/ { print $2,$3 }
  121.  
  122.         Finally if you want to find out if a string does not match a pattern 
  123. you use the not-match (!~) operator.
  124.  
  125. 1.4  Expressions
  126.  
  127.         Expressions in AWK are something that C programmers will be 
  128. comfortable with immediatly and those familiar with other languages could pick 
  129. up quickly.  You may be either disappointed or relieved by the restrictions on 
  130. expressions in AWK.  You cannot for instance get the address of anything, and 
  131. arrays are one-dimensional (multi-dimensions are simulated).  Most of the 
  132. power of the C language is available for expressions.
  133.  
  134.         Perhaps the most familiar expressions are those involving arithmetic 
  135. and assignment:
  136.  
  137.     a = b + c * 2           # a becomes b plus c times 2
  138.  
  139. A less familar kind of expression involves comparison and boolean operators:
  140.  
  141.     a > b && c == 1         # a is greater than b and c equals 1
  142.  
  143. You have already encountered the Field operator ($) and the pattern matching 
  144. operator (~):
  145.  
  146.     $1 ~ /[0-9]/            # field #1 contains a digit
  147.  
  148. The one operation that has no operator is string concatenation:
  149.  
  150.     name = name ".DAT"      # add file extension to name
  151.  
  152. Doubtless the least familiar to non C programmers is the conditional 
  153. assignment and the increment/decrement operators.
  154.  
  155.     x = (a > b) ? a-- : b-- # x becomes the greater of a and b then
  156.                             # decrement the greater of a or b
  157.  
  158.         Beware of the traps that some of these operators can let you fall 
  159. into.  The assignment operator can be used anywhere so if you use it instead 
  160. of the equality operator you will not get what you expect:
  161.  
  162.     a == 3                  # gives 1 if a is 3, otherwise 0
  163.     a = 3                   # gives 3 always and sets a to 3
  164.  
  165. So even the assignment expression has a value that can be used within a larger 
  166. expression: 
  167.  
  168.     b = (a = 5) + 2         # b becomes 7 and a becomes 5
  169.  
  170.         The comparison operators will do either a string comparison or a 
  171. numeric comparison depending on the arguments to the operation.
  172.  
  173.         If both left and right expressions are numeric then a numeric compare 
  174. is done otherwise a string compare is performed.  To force AWK to perform the 
  175. kind of comparison you want either you must ensure that both expressions are 
  176. numeric or one of them is string.  In the simplest case this can be done by 
  177. adding a zero to make it numeric or concatenating a null string to make it a 
  178. string. 
  179.  
  180.     3 < "10"                # false -- string compare
  181.     3 < 10                  # true -- numeric compare
  182.  
  183.         Fields, command line assignments, ARGV and the arrays created by the 
  184. split function have the special property of (possibly) being both a number and 
  185. a string.  If the field can be fully represented as a number by AWK then the 
  186. field will have the combined type and any variable that has been assigned the 
  187. value of one of these fields will have the combined type.  If both sides of a 
  188. comparison are combined type or one side is a number and the other is this 
  189. combined type then a numeric comparison is done. 
  190.  
  191. 1.5  Variables
  192.  
  193.         Variables spring into existance out of the ylem by being mentioned.  
  194. They can have either a numeric or string type.  The type of a variable is 
  195. determined by the type of the expression that is assigned to them: 
  196.  
  197.     a = x + 0               # a is a number
  198.     a = x ""                # a is a string
  199.  
  200.         Before any value is assigned to a variable it's type is indeterminate, 
  201. that is it is both a string and a number (this is important when doing 
  202. comparisons and for printing).  An uninitialized variable will compare equal 
  203. to the null string ("") and to zero (0).  It will print as the null string. 
  204.  
  205.     print (x, x=="", x==0)
  206.  
  207. will print:
  208.  
  209.      1 1
  210.  
  211. 1.6  Arrays
  212.  
  213.         Any variable can also be an array.  In AWK arrays are one-dimensional 
  214. but multi-dimensions are simulated by a BUILTIN VARIABLE called SUBSEP and 
  215. separating the subscripts with commas:
  216.  
  217.     a[1,2,3]
  218.  
  219. is equivalent to:
  220.  
  221.     a[1 SUBSEP 2 SUBSEP 3]
  222.  
  223. where the default value for SUBSEP is ascii ^Z (SUB).
  224.  
  225.         Arrays are indexed by strings so that the elements
  226.  
  227.     a["1"]
  228.  
  229. and
  230.  
  231.     a["01"]
  232.  
  233. are not the same, and also the elements
  234.  
  235.     a["1"]
  236.  
  237. and 
  238.  
  239.     a[1]
  240.  
  241. may or may not be the same depending on the Output Format (OFMT).
  242.  
  243.         Since arrays are indexed by strings there must be a way of stepping 
  244. through the array using strings.  The way we do it is with a special form of 
  245. the for loop:
  246.  
  247.     for (index in array) print index, array
  248.  
  249. will step through the array (in lexical order) printing each index and the 
  250. associated array element.  You can still access arrays using numbers if they 
  251. have been put into the array using numbers, since the string representation 
  252. for the indeces will be the same (unless you change OFMT) between creating the 
  253. array and using it.
  254.  
  255.         One departure from most programming languages that this kind of array 
  256. provides is fractional indices for array elements.  You can for instance have 
  257. an array element indexed by any number:
  258.  
  259.     a[3.14159] = "pi"
  260.  
  261.         Once you have finished with an array element you may remove it using 
  262. the delete statement or assigning every element out of existance.
  263.  
  264.     delete a[pi]
  265.     a = ""
  266.  
  267.         Finally there is a test for array membership that you must use if you 
  268. don't want extra array elements since the very mention of an array element 
  269. will cause it to spring into existance.  You must use: 
  270.  
  271.     if (i in a) ...
  272.  
  273. because by using:
  274.  
  275.     if (a[i] == "") ...
  276.  
  277. you will create all kinds of unwanted array elements that consist of 
  278. uninitialized variables. 
  279.  
  280. 1.7  Built In Variables
  281.  
  282.         There are a number of variables that AWK defines so that you can 
  283. get information, control certain aspects of AWK and in two cases get extra 
  284. information about a function.
  285.  
  286.         Two variables give information about the command line, ARGC and ARGV. 
  287. ARGC is the number of arguments except the options and program that AWK itself 
  288. uses and ARGV is an array containing the value of the command line arguments 
  289. with ARGV[0] being AWK's name and ARGV[1] to ARGV[ARGC-1] the rest of the 
  290. command line arguments. 
  291.  
  292.         Information about the file being read in is contained in FILENAME, and 
  293. FNR which contains the number of records read from the current file.  Neither 
  294. of these variables have any valid meaning during a BEGIN or END action. 
  295.  
  296.         The variables that describe the current input record are NR the number 
  297. of records read so far, and NF the number of fields in the current record.  NF 
  298. will change anytime you assign the value of $0 or any field after $NF.  Any 
  299. fields between $NF and $n where n > NF will be set to the null string ("").
  300.  
  301.         Output is controlled by the Output Record Separator (ORS), the output 
  302. Field Separator (OFS), and the Output Format (OFMT).  If you print some items 
  303. such as:
  304.  
  305.     print 1.20, "test", 001
  306.  
  307. the each comma will be replaced by the OFS (default blank) and the ORS will be 
  308. printed at the end.  The numbers will be printed according to the OFMT 
  309. (default %.6g) so: 
  310.  
  311.     1.2 test 1
  312.  
  313. will be the result of the print statement.
  314.  
  315.         Input is controlled by the Record Separator (RS) and the Field 
  316. Separator (FS).  If the RS is the null string ("") then the input record is 
  317. delimited by a blank line.  If it is a string consisting of the newline ("\n") 
  318. then each line will be a record.  The FS has more versitility, it can be any 
  319. Regular Expression so you have full control over the parsing of fields. 
  320.  
  321.         The pseudo multi-dimensional array Subscript Separator (SUBSEP) is 
  322. described in the section on arrays.
  323.  
  324.         Finally the variables RLENGTH and RSTART are set by the match function 
  325. to be the length of the string matched and the index of the first character 
  326. matched respectivly.
  327.  
  328. 1.8  Control Structures
  329.  
  330.         AWK has three basic control structures for alternation, iteration, and 
  331. repetition.  They are respectivly the if statement, the while statement, and 
  332. the for statement. 
  333.  
  334.         The if statement allows two mutually exclusive paths of program 
  335. execution:
  336.  
  337.     if (a > b) print "yes"; else print "no"
  338.  
  339. either of the paths may be a null statement, and if the second statement is 
  340. omitted then the else keyword may also be omitted:
  341.  
  342.     if (command == "print") print
  343.  
  344.         The while statement comes in two flavours, test first, and test last.  
  345. The test last sort is know as the do-while statement.
  346.  
  347.     do i = a[i]; while (a[i] != 0)
  348.  
  349. And the test first as the wile statement.
  350.  
  351.     while (a[i] != 0) i = a[i]
  352.  
  353. Both of these will continue to loop as long as the expression in parentheses 
  354. evaluates to true (non zero or non null).
  355.  
  356.         The for statement is a generalized loop generator in that any three 
  357. expressions can be used to control it.  Most often a familiar combination of 
  358. initialization, testing and modification is done:
  359.  
  360.     for (i = 0; i < ARGC; i++) print ARGV[i]
  361.  
  362. although the three expressions are not limited to this style of loop.  Indeed 
  363. any of the expressions may be omitted, the middle (test) expression will be 
  364. true if it is missing.  The for loop above is equivalent to: 
  365.  
  366.     i = 0; while (i < ARGC) { print ARGV[i]; i++ }
  367.  
  368. as you can see the first expression is evaluated before the loop, the second 
  369. is tested before the statement is executed and the third is evaluated after 
  370. the statement.
  371.  
  372.         The while, do-while, and for statements have two special statements 
  373. that can be used inside them to control the flow in extraordinary ways.  First 
  374. the break statement can be used to jump out of the loop entirely and second, 
  375. the continue statement is used to jump past the rest of the statements (in a 
  376. COMPOUND STATEMENT) and start another loop (at the third expression in the 
  377. case of the for loop). 
  378.  
  379.     for (i = 1; i < NF; i++) {
  380.         if ($i < 10) continue           # skip if < 10
  381.         if ($i > 20) break              # stop if > 20
  382.         x += $i                         # accumulate values
  383.     }
  384.  
  385.         Finally there are two statements that control the AWK program 
  386. globally.  They are the next and exit statements.  They function similarly to 
  387. the continue and break statements for loops.  The next statement will cause 
  388. the AWK program to stop in it's tracks and start with the next record.  The 
  389. exit statement will cause the AWK program to stop processing input records and 
  390. start the END actions (if any) or to stop altogether if the exit statement is 
  391. in an END action.
  392.  
  393.         There is an optional numeric argument to the exit statement that is 
  394. returned as the ERRORLEVEL of the program. 
  395.  
  396. 1.9  Statements
  397.  
  398.         There are four kinds of statements in AWK.  There are expressions, 
  399. flow-control, printing and compound statements.
  400.  
  401.         Expressions can be assignments or expressions with side effects.  For 
  402. instance: 
  403.  
  404.     a = a + 1
  405.  
  406. and
  407.  
  408.     a++
  409.  
  410. Expression with neither assignments nor side effects may be used as statements 
  411. but why bother?
  412.  
  413.         Flow control statements were outlined in section 1.8. 
  414.  
  415.         Compound statements are groups of statements delimited by braces that 
  416. may be used anywhere single statements are used (as in the flow control 
  417. statements). 
  418.  
  419.     for (i = 0; i < 4; i++) { sum = sum + a[i]; print i, a[i] }
  420.  
  421.         Statements may be separated by semi-colons (;) or by the end-of-line.  
  422. If you want to extend a statement across more than one line you break the line 
  423. with a backslash (\).  You may break a statement without a backslash after a 
  424. comma, left brace, &&, ||, do, else and the right parenthesis in an if or for 
  425. statement.
  426.  
  427.     if (a > b ||
  428.         c < d)
  429.     {
  430.         print ("silly",
  431.                "program"); print a,b,c,d
  432.     }
  433.  
  434.         A comment beginning with the octothorp (#) may be put at the end of 
  435. any line (including a blank line.)
  436.  
  437.     # print current record
  438.     print                   # printing current record ($0)
  439.                             # current record printed
  440.  
  441. 2.   Advanced Concepts
  442.  
  443. 2.1  Functions
  444.  
  445.         AWK allows you to write your own functions.  Two keywords are provided 
  446. for this purpose.  They are function and return, for definition and value 
  447. respectivly.  You declare a function with a special pattern action pair.
  448.  
  449.     function factorial(a) { return (a <= 1) ? 1 : factorial(a-1) * a }
  450.  
  451. You invoke the function as normal, there must be no space between the function 
  452. name and the left parenthesis.  Any extra argument that you provide are 
  453. evaluated and discarded, and any parameters that you do not provide arguments 
  454. for become uninitialized local variables. 
  455.  
  456.     function print_array(a, i) { for (i in a) print i, a[i] }
  457.     { telephone[$1] = $2 }          # collect name/telno
  458.     END {
  459.         print_array(telephone)      # print name and telno
  460.     }
  461.     .
  462.     harry_rag (111)555-1212
  463.  
  464.         When you are using recursive functions like factorial, you should be 
  465. aware that there is a limit on the level of recursion that you can do because 
  466. of the size of the evaluation stack. 
  467.  
  468. 3.   Anatomy of an AWK program
  469.  
  470. 3.1  The Problem
  471.  
  472.         (MS|PC)DOS normally prints the dates of files in a directory in the 
  473. form MM-DD-YY.  The problem is to convert that to the form DD-Mmm-YY where Mmm 
  474. is the first three letters of each month. 
  475.  
  476. 3.2  The Data
  477.  
  478.  Volume in drive C is R_DUFF     
  479.  Directory of  C:\AWK
  480.  
  481. .            <DIR>     11-16-88   1:53p
  482. ..           <DIR>     11-16-88   1:53p
  483. AWK             23721  11-16-88   2:15p
  484. AWK      C      14945   1-24-89   9:20p
  485. AWK      DOC    15791   2-19-89   5:09p
  486. AWK      EXE   118361   2-19-89   3:18p
  487. AWK      H       5380  11-13-88   1:58p
  488. AWK      MAN    19552  11-20-88  12:15p
  489. AWK      OBJ    10132   1-24-89   9:20p
  490.         9 File(s)   7235584 bytes free
  491.  
  492.         Here there are two kinds of records with dates and four without dates.  
  493. The two with dates are 4 and 5 fields long, and the ones without dates are 6, 
  494. 3 and 5 fields long.  Since we only want to modify the fields that have dates 
  495. in them we have to differentiate between the two types of size 5 records.
  496.  
  497. 3.2  The Program
  498.  
  499.         We have a BEGIN section, followed by a function declaration, followed 
  500. by three pattern/action statements. 
  501.  
  502. # dir - list directory with date interpretation
  503. BEGIN {
  504.     split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", month, " ");
  505. }
  506.  
  507.         The BEGIN section creates the month interpretation array.
  508.  
  509. function date(i) {
  510.     if ($i ~ /[0-9]+-[0-9]+-[0-9]+/) {
  511.         n = split($i, mdy, "-")
  512.         mdy[1] = month[int(mdy[1])]
  513.         $i = sprintf("%2d-%3s-%02d", mdy[2], mdy[1], mdy[3])
  514.         return 1
  515.     }
  516.     return 0
  517. }
  518.  
  519.         The date function checks with a regular expression for a valid date in 
  520. a particular field.  The regular expression matches 1 or more digits ([0-9]+) 
  521. followed by a dash (-), followed by 1 or more digits (again) followed by 
  522. another dash, finally ending with 1 or more digits.  This is the three numbers 
  523. separated by digits that MSDOS uses for dates. 
  524.  
  525.         If the date is valid then the field is split into sub-fields at the 
  526. dashes by the split function.  This will give an array (mdy) with three 
  527. elements corresponding to the three numbers in the date.  The month sub field 
  528. is replaced by the three character name from the month array by coercing the 
  529. month number to numeric (to remove leading zeros) and using this as an index 
  530. into the array generated in the BEGIN action.  The sub-fields are then 
  531. reassembled into the format that we want using sprintf.  The day first 
  532. (mdy[2]) followed by the month name (mdy[1]), followed by the year (mdy[3]), 
  533. all separated by dashes.  This string is assigned to the field that we just 
  534. took apart.  Finally a success code is returned (1).
  535.  
  536.         If the date is not valid then only the failure code is returned and no 
  537. substitution is performed.
  538.  
  539. NF == 5 {
  540.     if (date(4))
  541.         $0 = sprintf("%-9s%-3s%9s%11s%8s", $1,$2,$3,$4,$5)
  542. }
  543.  
  544.         This pattern check for those records that have 5 fields in them. They 
  545. are of two types:
  546.  
  547.     AWK      MAN    19552  11-20-88  12:15p
  548.  
  549. and
  550.  
  551.     9 File(s)   7235584 bytes free
  552.  
  553. only the first type is one that we have a date to change in.  We therefore 
  554. check field number 4 for a date and if it is one then we change the record to 
  555. use the fields in the correct format for our new date.  If we didn't use 
  556. sprintf and assign a new value to $0 then all of the fields would be separated 
  557. by a blank (ORS) instead of nicely lined up.
  558.  
  559. NF == 4 {
  560.     date(3)
  561.     if ($2 ~ /<DIR>/)
  562.         $0 = sprintf("%-9s%9s%14s%8s", $1,$2,$3,$4)
  563.     else
  564.         $0 = sprintf("%-9s%12s%11s%8s", $1,$2,$3,$4)
  565. }
  566.  
  567.         This pattern check for those records that have 4 fields in them. They 
  568. are of two types:
  569.  
  570.     AWK             23721  11-16-88   2:15p
  571.  
  572. and
  573.  
  574.     ..           <DIR>     11-16-88   1:53p
  575.  
  576. they both have dates in them at the same field but we want to format them 
  577. differently.  You will notice that the file size and the <DIR> indication do 
  578. not line up so we must format them separatly.  Hence we use our date function 
  579. to fix up the third field and then format one way if the second field matches 
  580. with the <DIR> indicator and format another way if it doesn't.
  581.  
  582. { print }
  583.  
  584.         Finally we get to print every record, some modified by the preceding 
  585. actions and some in their origional form.
  586.  
  587. 3.3  The Output
  588.  
  589.  Volume in drive C is R_DUFF     
  590.  Directory of  C:\SRC\AWK
  591.  
  592. .            <DIR>     16-Nov-88   1:53a
  593. ..           <DIR>     16-Nov-88   1:53a
  594. AWK             23721  16-Nov-88   2:15a
  595. AWK      C      14945  24-Jan-89   9:20p
  596. AWK      DOC    15791  19-Feb-89   5:09p
  597. AWK      EXE   118361  19-Feb-89   3:18p
  598. AWK      H       5380  13-Nov-88   1:58p
  599. AWK      MAN    19552  20-Nov-88  12:15p
  600. AWK      OBJ    10132  24-Jan-89   9:20p
  601.         9 File(s)   7235584 bytes free
  602.  
  603. 3.4  Conclusion
  604.  
  605.         The result ends looking much the same as the input but with a more 
  606. readable date.  We thus have created an AWK program that can be used to pretty 
  607. up directories.
  608.  
  609.