aboutsummaryrefslogtreecommitdiffstats
path: root/doc/gawk.texi
diff options
context:
space:
mode:
Diffstat (limited to 'doc/gawk.texi')
-rw-r--r--doc/gawk.texi200
1 files changed, 118 insertions, 82 deletions
diff --git a/doc/gawk.texi b/doc/gawk.texi
index a8c9245d..65e5cd91 100644
--- a/doc/gawk.texi
+++ b/doc/gawk.texi
@@ -6041,6 +6041,7 @@ used with it do not have to be named on the @command{awk} command line
* Command line directories:: What happens if you put a directory on the
command line.
* Input Summary:: Input summary.
+* Input Exercises:: Exercises.
@end menu
@node Records
@@ -7475,10 +7476,6 @@ program for processing such data could use the @code{FIELDWIDTHS} feature
to simplify reading the data. (Of course, getting @command{gawk} to run on
a system with card readers is another story!)
-@ignore
-Exercise: Write a ballot card reading program
-@end ignore
-
@cindex @command{gawk}, splitting fields and
Assigning a value to @code{FS} causes @command{gawk} to use
@code{FS} for field splitting again. Use @samp{FS = FS} to make this happen,
@@ -7915,11 +7912,6 @@ decommented input, such as searching for matches of a regular
expression. (This program has a subtle problem---it does not work if one
comment ends and another begins on the same line.)
-@ignore
-Exercise,
-write a program that does handle multiple comments on the line.
-@end ignore
-
This form of the @code{getline} command sets @code{NF},
@code{NR}, @code{FNR}, @code{RT}, and the value of @code{$0}.
@@ -8118,7 +8110,6 @@ each one.
@xref{Close Files And Pipes}.
@end ifnotdocbook
@end ifnottex
-@c Exercise!!
@c This example is unrealistic, since you could just use system
Given the input:
@@ -8589,6 +8580,26 @@ Directories on the command line are fatal for standard @command{awk};
@end itemize
+@node Input Exercises
+@section Exercises
+
+@enumerate
+@item
+Using the @code{FIELDWIDTHS} variable (@pxref{Constant Size}),
+write a program to read election data, where each record represents
+one voter's votes. Come up with a way to define which columns are
+associated with each ballot item, and print the total votes,
+including abstentions, for each item.
+
+@item
+@ref{Plain Getline}, presented a program to remove C-style
+comments (@samp{/* @dots{} */}) from the input. That program
+does not work if one comment ends on one line and another one
+starts later on the same line.
+Write a program that does handle multiple comments on the line.
+
+@end enumerate
+
@node Printing
@chapter Printing Output
@@ -8629,6 +8640,7 @@ and discusses the @code{close()} built-in function.
descriptors.
* Close Files And Pipes:: Closing Input and Output Files and Pipes.
* Output Summary:: Output summary.
+* Output exercises:: Exercises.
@end menu
@node Print
@@ -8806,16 +8818,6 @@ The following example prints the first and second fields of each input
record, separated by a semicolon, with a blank line added after each
newline:
-@ignore
-Exercise,
-Rewrite the
-@example
-awk 'BEGIN @{ print "Month Crates"
- print "----- ------" @}
- @{ print $1, " ", $2 @}' inventory-shipped
-@end example
-program by using a new value of @code{OFS}.
-@end ignore
@example
$ @kbd{awk 'BEGIN @{ OFS = ";"; ORS = "\n\n" @}}
@@ -9377,12 +9379,6 @@ awk 'BEGIN @{ format = "%-10s %s\n"
@{ printf format, $1, $2 @}' mail-list
@end example
-@c !!! exercise
-At this point, it would be a worthwhile exercise to use the
-@code{printf} statement to line up the headings and table data for the
-@file{inventory-shipped} example that was covered earlier in the @value{SECTION}
-on the @code{print} statement
-(@pxref{Print}).
@c ENDOFRANGE printfs
@node Redirection
@@ -9771,7 +9767,6 @@ Note the use of quotes around the @value{FN}.
Like any other redirection, the value must be a string.
It is a common error to omit the quotes, which leads
to confusing results.
-@c Exercise: What does it do? :-)
Finally, using the @code{close()} function on a @value{FN} of the
form @code{"/dev/fd/@var{N}"}, for file descriptor numbers
@@ -10149,6 +10144,35 @@ communications.
@end itemize
+@node Output exercises
+@section Exercises
+
+@enumerate
+@item
+Rewrite the program:
+
+@example
+awk 'BEGIN @{ print "Month Crates"
+ print "----- ------" @}
+ @{ print $1, " ", $2 @}' inventory-shipped
+@end example
+
+@noindent
+from @ref{Output Separators}, by using a new value of @code{OFS}.
+
+@item
+Use the @code{printf} statement to line up the headings and table data
+for the @file{inventory-shipped} example that was covered in @ref{Print}.
+
+@item
+What happens if you forget the double quotes when redirecting
+output, as follows:
+
+@example
+BEGIN @{ print "Serious error detected!" > /dev/stderr @}
+@end example
+
+@end enumerate
@c ENDOFRANGE prnt
@@ -20143,6 +20167,7 @@ comparisons use only lowercase letters.
* Group Functions:: Functions for getting group information.
* Walking Arrays:: A function to walk arrays of arrays.
* Library Functions Summary:: Summary of library functions.
+* Library exercises:: Exercises.
@end menu
@node Library Names
@@ -21303,46 +21328,6 @@ the end of the command-line arguments. Note that the test in the
condition of the @code{for} loop uses the @samp{<=} operator,
not @samp{<}.
-As an exercise, you might consider whether this same problem can
-be solved without relying on @command{gawk}'s @code{ARGIND} variable.
-
-As a second exercise, revise this code to handle the case where
-an intervening value in @code{ARGV} is a variable assignment.
-
-@ignore
-# zerofile2.awk --- same thing, portably
-
-BEGIN @{
- ARGIND = Argind = 0
- for (i = 1; i < ARGC; i++)
- Fnames[ARGV[i]]++
-
-@}
-FNR == 1 @{
- while (ARGV[ARGIND] != FILENAME)
- ARGIND++
- Seen[FILENAME]++
- if (Seen[FILENAME] == Fnames[FILENAME])
- do
- ARGIND++
- while (ARGV[ARGIND] != FILENAME)
-@}
-ARGIND > Argind + 1 @{
- for (Argind++; Argind < ARGIND; Argind++)
- zerofile(ARGV[Argind], Argind)
-@}
-ARGIND != Argind @{
- Argind = ARGIND
-@}
-END @{
- if (ARGIND < ARGC - 1)
- ARGIND = ARGC - 1
- if (ARGIND > Argind)
- for (Argind++; Argind <= ARGIND; Argind++)
- zerofile(ARGV[Argind], Argind)
-@}
-@end ignore
-
@node Ignoring Assigns
@subsection Treating Assignments as @value{FFN}s
@@ -22551,21 +22536,6 @@ $ @kbd{gawk -f walk_array.awk}
@print{} a[3] = 3
@end example
-@c exercise!
-Walking an array and processing each element is a general-purpose
-operation. You might want to consider generalizing the @code{walk_array()}
-function by adding an additional parameter named @code{process}.
-
-Then, inside the loop, instead of simply printing the array element's
-index and value, use the indirect function call syntax
-(@pxref{Indirect Calls}) on @code{process}, passing it the index
-and the value.
-
-When calling @code{walk_array()}, you would pass the name of a user-defined
-function that expects to receive an index and a value, and then processes
-the element.
-
-
@c ENDOFRANGE libfgdata
@c ENDOFRANGE flibgdata
@c ENDOFRANGE gdatar
@@ -22614,6 +22584,72 @@ A simple function to traverse an array of arrays to any depth.
@end itemize
+@node Library exercises
+@section Exercises
+
+@enumerate
+@item
+In @ref{Empty Files}, we presented the @file{zerofile.awk} program,
+which made use of @command{gawk}'s @code{ARGIND} variable. Can this
+problem be solved without relying on @code{ARGIND}? If so, how?
+
+@ignore
+# zerofile2.awk --- same thing, portably
+
+BEGIN @{
+ ARGIND = Argind = 0
+ for (i = 1; i < ARGC; i++)
+ Fnames[ARGV[i]]++
+
+@}
+FNR == 1 @{
+ while (ARGV[ARGIND] != FILENAME)
+ ARGIND++
+ Seen[FILENAME]++
+ if (Seen[FILENAME] == Fnames[FILENAME])
+ do
+ ARGIND++
+ while (ARGV[ARGIND] != FILENAME)
+@}
+ARGIND > Argind + 1 @{
+ for (Argind++; Argind < ARGIND; Argind++)
+ zerofile(ARGV[Argind], Argind)
+@}
+ARGIND != Argind @{
+ Argind = ARGIND
+@}
+END @{
+ if (ARGIND < ARGC - 1)
+ ARGIND = ARGC - 1
+ if (ARGIND > Argind)
+ for (Argind++; Argind <= ARGIND; Argind++)
+ zerofile(ARGV[Argind], Argind)
+@}
+@end ignore
+
+@item
+As a related challenge, revise that code to handle the case where
+an intervening value in @code{ARGV} is a variable assignment.
+
+@item
+@ref{Walking Arrays}, presented a function that walked a multidimensional
+array to print it out. However, walking an array and processing
+each element is a general-purpose operation. Generalize the
+@code{walk_array()} function by adding an additional parameter named
+@code{process}.
+
+Then, inside the loop, instead of printing the array element's index and
+value, use the indirect function call syntax (@pxref{Indirect Calls})
+on @code{process}, passing it the index and the value.
+
+When calling @code{walk_array()}, you would pass the name of a
+user-defined function that expects to receive an index and a value,
+and then processes the element.
+
+Test your new version by printing the array; you should end up with
+output identical to that of the original version.
+
+@end enumerate
@c ENDOFRANGE flib
@c ENDOFRANGE fudlib