[BACK]Return to awk.1 CVS log [TXT][DIR] Up to [local] / src / usr.bin / awk

Diff for /src/usr.bin/awk/awk.1 between version 1.6 and 1.7

version 1.6, 1999/06/05 01:21:18 version 1.7, 2000/08/30 13:37:51
Line 1 
Line 1 
 .\"     $OpenBSD$  .\"     $OpenBSD$
 .de EX  .\" EX/EE is a Bd
 .nf  .Dd June 29, 1996
 .ft CW  .Dt AWK 1
 ..  .Os
 .de EE  .Sh NAME
 .br  .Nm awk
 .fi  .Nd pattern-directed scanning and processing language
 .ft 1  .Sh SYNOPSIS
 ..  .Nm awk
 .TH AWK 1  .Op Fl F Ar fs
 .CT 1 files prog_other  .Op Fl v Ar var=value
 .SH NAME  .Op Fl safe
 awk \- pattern-directed scanning and processing language  .Op Fl mr Ar n
 .SH SYNOPSIS  .Op Fl mf Ar n
 .B awk|nawk  .Op Ar prog | Fl f Ar progfile
 [  .Ar
 .BI \-F  .Nm nawk
 .I fs  .Ar ...
 ]  .Sh DESCRIPTION
 [  .Nm
 .BI \-v  
 .I var=value  
 ]  
 [  
 .BI \-safe  
 ]  
 [  
 .BI \-mr n  
 ]  
 [  
 .BI \-mf n  
 ]  
 [  
 .I 'prog'  
 |  
 .BI \-f  
 .I progfile  
 ]  
 [  
 .I file ...  
 ]  
 .SH DESCRIPTION  
 .I Awk  
 scans each input  scans each input
 .I file  .Ar file
 for lines that match any of a set of patterns specified literally in  for lines that match any of a set of patterns specified literally in
 .IR prog  .Ar prog
 or in one or more files  or in one or more files
 specified as  specified as
 .B \-f  .Fl f Ar progfile .
 .IR progfile .  
 With each pattern  With each pattern
 there can be an associated action that will be performed  there can be an associated action that will be performed
 when a line of a  when a line of a
 .I file  .Ar file
 matches the pattern.  matches the pattern.
 Each line is matched against the  Each line is matched against the
 pattern portion of every pattern-action statement;  pattern portion of every pattern-action statement;
 the associated action is performed for each matched pattern.  the associated action is performed for each matched pattern.
 The file name  The file name
 .B \-  .Sq Pa \-
 means the standard input.  means the standard input.
 Any  Any
 .IR file  .Ar file
 of the form  of the form
 .I var=value  .Ar var=value
 is treated as an assignment, not a filename,  is treated as an assignment, not a filename,
 and is executed at the time it would have been opened if it were a filename.  and is executed at the time it would have been opened if it were a filename.
 The option  The option
 .B \-v  .Fl v
 followed by  followed by
 .I var=value  .Ar var=value
 is an assignment to be done before  is an assignment to be done before
 .I prog  .Ar prog
 is executed;  is executed;
 any number of  any number of
 .B \-v  .Fl v
 options may be present.  options may be present.
 The  The
 .B \-F  .Fl F Ar fs
 .IR fs  
 option defines the input field separator to be the regular expression  option defines the input field separator to be the regular expression
 .IR fs.  .Ar fs .
 The  The
 .B \-safe  .Fl safe
 option disables file output (print >, print >>), process creation  option disables file output
 (cmd|getline, print |, system), and access to the environment (ENVIRON). This  .Po
 is a first (and not very reliable) approximation to a "safe" version of awk.  .Ic print Ic > ,
 .PP  .Ic print Ic >> ,
 An input line is normally made up of fields separated by white space,  .Pc
   process creation
   .Po
   .Ar cmd Ic \&| getline ,
   .Ic print \&| , system
   .Pc
   and access to the environment
   .Pq Va ENVIRON .
   This
   is a first (and not very reliable) approximation to a
   .Dq safe
   version of
   .Nm awk .
   .Pp
   An input line is normally made up of fields separated by whitespace,
 or by regular expression  or by regular expression
 .BR FS .  .Va FS .
 The fields are denoted  The fields are denoted
 .BR $1 ,  .Va $1 , $2 , ... ,
 .BR $2 ,  while
 \&..., while  .Va $0
 .B $0  
 refers to the entire line.  refers to the entire line.
 If  If
 .BR FS  .Va FS
 is null, the input line is split into one field per character.  is null, the input line is split into one field per character.
 .PP  .Pp
 To compensate for inadequate implementation of storage management,  To compensate for inadequate implementation of storage management,
 the  the
 .B \-mr  .Fl mr
 option can be used to set the maximum size of the input record,  option can be used to set the maximum size of the input record,
 and the  and the
 .B \-mf  .Fl mf
 option to set the maximum number of fields.  option to set the maximum number of fields.
 .PP  .Pp
 A pattern-action statement has the form  A pattern-action statement has the form
 .IP  .Pp
 .IB pattern " { " action " }  .D1 Ar pattern Ic \&{ Ar action Ic \&}
 .PP  .Pp
 A missing  A missing
 .BI { " action " }  .Ic \&{ Ar action Ic \&}
 means print the line;  means print the line;
 a missing pattern always matches.  a missing pattern always matches.
 Pattern-action statements are separated by newlines or semicolons.  Pattern-action statements are separated by newlines or semicolons.
 .PP  .Pp
 An action is a sequence of statements.  An action is a sequence of statements.
 A statement can be one of the following:  A statement can be one of the following:
 .PP  .Pp
 .EX  .Bd -unfilled -offset indent
 .ta \w'\f(CWdelete array[expression]'u  .Ic if ( Xo
 .RS  .Ar expression ) statement \&
 .nf  .Op Ic else Ar statement
 .ft CW  .Xc
 if(\fI expression \fP)\fI statement \fP\fR[ \fPelse\fI statement \fP\fR]\fP  .Ic while ( Ar expression ) statement
 while(\fI expression \fP)\fI statement\fP  .Ic for ( Xo
 for(\fI expression \fP;\fI expression \fP;\fI expression \fP)\fI statement\fP  .Ar expression ; expression ; expression ) statement
 for(\fI var \fPin\fI array \fP)\fI statement\fP  .Xc
 do\fI statement \fPwhile(\fI expression \fP)  .Ic for ( Xo
 break  .Ar var Ic in Ar array ) statement
 continue  .Xc
 {\fR [\fP\fI statement ... \fP\fR] \fP}  .Ic do Ar statement Ic while ( Ar expression )
 \fIexpression\fP        #\fR commonly\fP\fI var = expression\fP  .Ic break
 print\fR [ \fP\fIexpression-list \fP\fR] \fP\fR[ \fP>\fI expression \fP\fR]\fP  .Ic continue
 printf\fI format \fP\fR[ \fP,\fI expression-list \fP\fR] \fP\fR[ \fP>\fI expression \fP\fR]\fP  .Ic { Oo Ar statement ... Oc Ic \& }
 return\fR [ \fP\fIexpression \fP\fR]\fP  .Ar expression Xo
 next    #\fR skip remaining patterns on this input line\fP  .No "# commonly" \&
 nextfile        #\fR skip rest of this file, open next, start at top\fP  .Ar var Ic = Ar expression
 delete\fI array\fP[\fI expression \fP]  #\fR delete an array element\fP  .Xc
 delete\fI array\fP      #\fR delete all elements of array\fP  .Ic print Xo
 exit\fR [ \fP\fIexpression \fP\fR]\fP   #\fR exit immediately; status is \fP\fIexpression\fP  .Op Ar expression-list
 .fi  .Op Ic > Ns Ar expression
 .RE  .Xc
 .EE  .Ic printf Ar format Xo
 .DT  .Op Ar ... , expression-list
 .PP  .Op Ic > Ns Ar expression
   .Xc
   .Ic return Op Ar expression
   .Ic next Xo
   .No "# skip remaining patterns on this input line"
   .Xc
   .Ic nextfile Xo
   .No "# skip rest of this file, open next, start at top"
   .Xc
   .Ic delete Ar array Ns Xo
   .Ic \&[ Ns Ar expression Ns Ic \&]
   .No \& "# delete an array element"
   .Xc
   .Ic delete Ar array Xo
   .No "# delete all elements of array"
   .Xc
   .Ic exit Xo
   .Op Ar expression
   .No \& "# exit immediately; status is" Ar expression
   .Xc
   .Ed
   .Pp
 Statements are terminated by  Statements are terminated by
 semicolons, newlines or right braces.  semicolons, newlines or right braces.
 An empty  An empty
 .I expression-list  .Ar expression-list
 stands for  stands for
 .BR $0 .  .Ar $0 .
 String constants are quoted \&\f(CW"\ "\fR,  String constants are quoted
   .Li \&"" ,
 with the usual C escapes recognized within.  with the usual C escapes recognized within.
 Expressions take on string or numeric values as appropriate,  Expressions take on string or numeric values as appropriate,
 and are built using the operators  and are built using the operators
 .B + \- * / % ^  .Ic + \- * / % ^
 (exponentiation), and concatenation (indicated by white space).  (exponentiation), and concatenation (indicated by whitespace).
 The operators  The operators
 .B  .Ic ! ++ \-\- += \-= *= /= %= ^= > >= < <= == != ?:
 ! ++ \-\- += \-= *= /= %= ^= > >= < <= == != ?:  
 are also available in expressions.  are also available in expressions.
 Variables may be scalars, array elements  Variables may be scalars, array elements
 (denoted  (denoted
 .IB x  [ i ] )  .Li x[i] )
 or fields.  or fields.
 Variables are initialized to the null string.  Variables are initialized to the null string.
 Array subscripts may be any string,  Array subscripts may be any string,
 not necessarily numeric;  not necessarily numeric;
 this allows for a form of associative memory.  this allows for a form of associative memory.
 Multiple subscripts such as  Multiple subscripts such as
 .B [i,j,k]  .Li [i,j,k]
 are permitted; the constituents are concatenated,  are permitted; the constituents are concatenated,
 separated by the value of  separated by the value of
 .BR SUBSEP .  .Va SUBSEP .
 .PP  .Pp
 The  The
 .B print  .Ic print
 statement prints its arguments on the standard output  statement prints its arguments on the standard output
 (or on a file if  (or on a file if
 .BI > file  .Ic > Ns Ar file
 or  or
 .BI >> file  .Ic >> Ns Ar file
 is present or on a pipe if  is present or on a pipe if
 .BI | cmd  .Ic \&| Ar cmd
 is present), separated by the current output field separator,  is present), separated by the current output field separator,
 and terminated by the output record separator.  and terminated by the output record separator.
 .I file  .Ar file
 and  and
 .I cmd  .Ar cmd
 may be literal names or parenthesized expressions;  may be literal names or parenthesized expressions;
 identical string values in different statements denote  identical string values in different statements denote
 the same open file.  the same open file.
 The  The
 .B printf  .Ic printf
 statement formats its expression list according to the format  statement formats its expression list according to the format
 (see  (see
 .IR printf (3)) .  .Xr printf 3 .
 The built-in function  The built-in function
 .BI close( expr )  .Fn close expr
 closes the file or pipe  closes the file or pipe
 .IR expr .  .Fa expr .
 The built-in function  The built-in function
 .BI fflush( expr )  .Fn fflush expr
 flushes any buffered output for the file or pipe  flushes any buffered output for the file or pipe
 .IR expr .  .Fa expr .
 .PP  .Pp
 The mathematical functions  The mathematical functions
 .BR exp ,  .Fn exp ,
 .BR log ,  .Fn log ,
 .BR sqrt ,  .Fn sqrt ,
 .BR sin ,  .Fn sin ,
 .BR cos ,  .Fn cos ,
 and  and
 .BR atan2  .Fn atan2
 are built in.  are built in.
 Other built-in functions:  Other built-in functions:
 .TF length  .Pp
 .TP  .Bl -tag -width Fn
 .B length  .It Fn length
 the length of its argument  the length of its argument
 taken as a string,  taken as a string,
 or of  or of
 .B $0  .Va $0
 if no argument.  if no argument.
 .TP  .It Fn rand
 .B rand  
 random number on (0,1)  random number on (0,1)
 .TP  .It Fn srand
 .B srand  
 sets seed for  sets seed for
 .B rand  .Fn rand
 and returns the previous seed.  and returns the previous seed.
 .TP  .It Fn int
 .B int  truncates to an integer value.
 truncates to an integer value  .It Fn substr s m n
 .TP  
 .BI substr( s , " m" , " n\fB)  
 the  the
 .IR n -character  .Fa n Ns No -character
 substring of  substring of
 .I s  .Fa s
 that begins at position  that begins at position
 .IR m  .Fa m
 counted from 1.  counted from 1.
 .TP  .It Fn index s t
 .BI index( s , " t" )  
 the position in  the position in
 .I s  .Fa s
 where the string  where the string
 .I t  .Fa t
 occurs, or 0 if it does not.  occurs, or 0 if it does not.
 .TP  .It Fn match s r
 .BI match( s , " r" )  
 the position in  the position in
 .I s  .Fa s
 where the regular expression  where the regular expression
 .I r  .Fa r
 occurs, or 0 if it does not.  occurs, or 0 if it does not.
 The variables  The variables
 .B RSTART  .Va RSTART
 and  and
 .B RLENGTH  .Va RLENGTH
 are set to the position and length of the matched string.  are set to the position and length of the matched string.
 .TP  .It Fn split s a fs
 .BI split( s , " a" , " fs\fB)  
 splits the string  splits the string
 .I s  .Fa s
 into array elements  into array elements
 .IB a [1] ,  .Va a[1] , a[2] , ... , a[n]
 .IB a [2] ,  
 \&...,  
 .IB a [ n ] ,  
 and returns  and returns
 .IR n .  .Va n .
 The separation is done with the regular expression  The separation is done with the regular expression
 .I fs  .Ar fs
 or with the field separator  or with the field separator
 .B FS  .Va FS
 if  if
 .I fs  .Ar fs
 is not given.  is not given.
 An empty string as field separator splits the string  An empty string as field separator splits the string
 into one array element per character.  into one array element per character.
 .TP  .It Fn sub r t s
 .BI sub( r , " t" , " s\fB)  
 substitutes  substitutes
 .I t  .Fa t
 for the first occurrence of the regular expression  for the first occurrence of the regular expression
 .I r  .Fa r
 in the string  in the string
 .IR s .  .Fa s .
 If  If
 .I s  .Fa s
 is not given,  is not given,
 .B $0  .Va $0
 is used.  is used.
 .TP  .It Fn gsub r t s
 .B gsub  
 same as  same as
 .B sub  .Fn sub
 except that all occurrences of the regular expression  except that all occurrences of the regular expression
 are replaced;  are replaced;
 .B sub  .Fn sub
 and  and
 .B gsub  .Fn gsub
 return the number of replacements.  return the number of replacements.
 .TP  .It Fn sprintf fmt expr ...
 .BI sprintf( fmt , " expr" , " ...\fB )  
 the string resulting from formatting  the string resulting from formatting
 .I expr ...  .Fa expr , ...
 according to the  according to the
 .IR printf (3)  .Xr printf 3
 format  format
 .I fmt  .Fa fmt .
 .TP  .It Fn system cmd
 .BI system( cmd )  
 executes  executes
 .I cmd  .Fa cmd
 and returns its exit status  and returns its exit status.
 .TP  .It Fn tolower str
 .BI tolower( str )  
 returns a copy of  returns a copy of
 .I str  .Fa str
 with all upper-case characters translated to their  with all upper-case characters translated to their
 corresponding lower-case equivalents.  corresponding lower-case equivalents.
 .TP  .It Fn toupper str
 .BI toupper( str )  
 returns a copy of  returns a copy of
 .I str  .Fa str
 with all lower-case characters translated to their  with all lower-case characters translated to their
 corresponding upper-case equivalents.  corresponding upper-case equivalents.
 .PD  .El
 .PP  .Pp
 The ``function''  The
 .B getline  .Sq function
   .Ic getline
 sets  sets
 .B $0  .Va $0
 to the next input record from the current input file;  to the next input record from the current input file;
 .B getline  .Ic getline < Ar file
 .BI < file  
 sets  sets
 .B $0  .Va $0
 to the next record from  to the next record from
 .IR file .  .Ar file .
 .B getline  .Ic getline Va x
 .I x  
 sets variable  sets variable
 .I x  .Va x
 instead.  instead.
 Finally,  Finally,
 .IB cmd " | getline  .Ar cmd Ic \&| getline
 pipes the output of  pipes the output of
 .I cmd  .Ar cmd
 into  into
 .BR getline ;  .Ic getline ;
 each call of  each call of
 .B getline  .Ic getline
 returns the next line of output from  returns the next line of output from
 .IR cmd .  .Ar cmd .
 In all cases,  In all cases,
 .B getline  .Ic getline
 returns 1 for a successful input,  returns 1 for a successful input,
 0 for end of file, and \-1 for an error.  0 for end of file, and \-1 for an error.
 .PP  .Pp
 Patterns are arbitrary Boolean combinations  Patterns are arbitrary Boolean combinations
 (with  (with
 .BR "! || &&" )  .Ic "! || &&" )
 of regular expressions and  of regular expressions and
 relational expressions.  relational expressions.
 Regular expressions are as in  Regular expressions are as in
 .IR egrep ;  .Xr egrep  1 .
 see  
 .IR grep (1).  
 Isolated regular expressions  Isolated regular expressions
 in a pattern apply to the entire line.  in a pattern apply to the entire line.
 Regular expressions may also occur in  Regular expressions may also occur in
 relational expressions, using the operators  relational expressions, using the operators
 .BR ~  .Ic ~
 and  and
 .BR !~ .  .Ic !~ .
 .BI / re /  .Ic / Ns Ar re Ns Ic /
 is a constant regular expression;  is a constant regular expression;
 any string (constant or variable) may be used  any string (constant or variable) may be used
 as a regular expression, except in the position of an isolated regular expression  as a regular expression, except in the position of an isolated regular expression
 in a pattern.  in a pattern.
 .PP  .Pp
 A pattern may consist of two patterns separated by a comma;  A pattern may consist of two patterns separated by a comma;
 in this case, the action is performed for all lines  in this case, the action is performed for all lines
 from an occurrence of the first pattern  from an occurrence of the first pattern
 though an occurrence of the second.  though an occurrence of the second.
 .PP  .Pp
 A relational expression is one of the following:  A relational expression is one of the following:
 .IP  .Bd -unfilled -offset indent
 .I expression matchop regular-expression  .Ar expression matchop regular-expression
 .br  .Ar expression relop expression
 .I expression relop expression  .Ar expression Ic in Ar array-name
 .br  .Ic \&( Ns Xo
 .IB expression " in " array-name  .Ar expr , expr , \&... Ns Ic \&) in
 .br  .Ar \& array-name
 .BI ( expr , expr,... ") in " array-name  .Xc
 .PP  .Ed
 where a relop is any of the six relational operators in C,  where a
 and a matchop is either  .Ar relop
 .B ~  is any of the six relational operators in C, and a
   .Ar matchop
   is either
   .Ic ~
 (matches)  (matches)
 or  or
 .B !~  .Ic !~
 (does not match).  (does not match).
 A conditional is an arithmetic expression,  A conditional is an arithmetic expression,
 a relational expression,  a relational expression,
 or a Boolean combination  or a Boolean combination
 of these.  of these.
 .PP  .Pp
 The special patterns  The special patterns
 .B BEGIN  .Ic BEGIN
 and  and
 .B END  .Ic END
 may be used to capture control before the first input line is read  may be used to capture control before the first input line is read
 and after the last.  and after the last.
 .B BEGIN  .Ic BEGIN
 and  and
 .B END  .Ic END
 do not combine with other patterns.  do not combine with other patterns.
 .PP  .Pp
 Variable names with special meanings:  Variable names with special meanings:
 .TF FILENAME  .Pp
 .TP  .Bl -tag -width Va -compact
 .B CONVFMT  .It Va CONVFMT
 conversion format used when converting numbers  conversion format used when converting numbers
 (default  (default
 .BR "%.6g" )  .Qq Li %.6g )
 .TP  .It Va FS
 .B FS  
 regular expression used to separate fields; also settable  regular expression used to separate fields; also settable
 by option  by option
 .BI \-F fs.  .Fl fs .
 .TP  .It Va NF
 .BR NF  
 number of fields in the current record  number of fields in the current record
 .TP  .It Va NR
 .B NR  
 ordinal number of the current record  ordinal number of the current record
 .TP  .It Va FNR
 .B FNR  
 ordinal number of the current record in the current file  ordinal number of the current record in the current file
 .TP  .It Va FILENAME
 .B FILENAME  
 the name of the current input file  the name of the current input file
 .TP  .It Va RS
 .B RS  
 input record separator (default newline)  input record separator (default newline)
 .TP  .It Va OFS
 .B OFS  
 output field separator (default blank)  output field separator (default blank)
 .TP  .It Va ORS
 .B ORS  
 output record separator (default newline)  output record separator (default newline)
 .TP  .It Va OFMT
 .B OFMT  
 output format for numbers (default  output format for numbers (default
 .BR "%.6g" )  .Qq Li %.6g )
 .TP  .It Va SUBSEP
 .B SUBSEP  
 separates multiple subscripts (default 034)  separates multiple subscripts (default 034)
 .TP  .It Va ARGC
 .B ARGC  
 argument count, assignable  argument count, assignable
 .TP  .It Va ARGV
 .B ARGV  
 argument array, assignable;  argument array, assignable;
 non-null members are taken as filenames  non-null members are taken as filenames
 .TP  .It Va ENVIRON
 .B ENVIRON  
 array of environment variables; subscripts are names.  array of environment variables; subscripts are names.
 .PD  .El
 .PP  .Pp
 Functions may be defined (at the position of a pattern-action statement) thus:  Functions may be defined (at the position of a pattern-action statement)
 .IP  thusly:
 .B  .Pp
 function foo(a, b, c) { ...; return x }  .Dl function foo(a, b, c) { ...; return x }
 .PP  .Pp
 Parameters are passed by value if scalar and by reference if array name;  Parameters are passed by value if scalar and by reference if array name;
 functions may be called recursively.  functions may be called recursively.
 Parameters are local to the function; all other variables are global.  Parameters are local to the function; all other variables are global.
 Thus local variables may be created by providing excess parameters in  Thus local variables may be created by providing excess parameters in
 the function definition.  the function definition.
 .SH EXAMPLES  .Sh EXAMPLES
 .TP  .Dl length($0) > 72
 .EX  
 length($0) > 72  
 .EE  
 Print lines longer than 72 characters.  Print lines longer than 72 characters.
 .TP  .Pp
 .EX  .Dl { print $2, $1 }
 { print $2, $1 }  
 .EE  
 Print first two fields in opposite order.  Print first two fields in opposite order.
 .PP  .Pp
 .EX  .Bd -literal -offset indent
 BEGIN { FS = ",[ \et]*|[ \et]+" }  BEGIN { FS = ",[ \et]*|[ \et]+" }
       { print $2, $1 }        { print $2, $1 }
 .EE  .Ed
 .ns  
 .IP  
 Same, with input fields separated by comma and/or blanks and tabs.  Same, with input fields separated by comma and/or blanks and tabs.
 .PP  .Pp
 .EX  .Bd -literal -offset indent
 .nf  { s += $1 }
         { s += $1 }  END { print "sum is", s, " average is", s/NR }
 END     { print "sum is", s, " average is", s/NR }  .Ed
 .fi  
 .EE  
 .ns  
 .IP  
 Add up first column, print sum and average.  Add up first column, print sum and average.
 .TP  .Pp
 .EX  .Dl /start/, /stop/
 /start/, /stop/  
 .EE  
 Print all lines between start/stop pairs.  Print all lines between start/stop pairs.
 .PP  .Pp
 .EX  .Bd -literal -offset indent
 .nf  BEGIN { # Simulate echo(1)
 BEGIN   {       # Simulate echo(1)          for (i = 1; i < ARGC; i++) printf "%s ", ARGV[i]
         for (i = 1; i < ARGC; i++) printf "%s ", ARGV[i]          printf "\en"
         printf "\en"          exit }
         exit }  .Ed
 .fi  .Sh SEE ALSO
 .EE  .Xr lex 1 ,
 .SH SEE ALSO  .Xr sed 1
 .IR lex (1),  .Rs
 .IR sed (1)  .%A A. V. Aho
 .br  .%A B. W. Kernighan
 A. V. Aho, B. W. Kernighan, P. J. Weinberger,  .%A P. J. Weinberger
 .I  .%T The AWK Programming Language
 The AWK Programming Language,  .%I Addison-Wesley
 Addison-Wesley, 1988.  ISBN 0-201-07981-X  .%D 1988
 .SH BUGS  .%O ISBN 0-201-07981-X
   .Re
   .Sh BUGS
 There are no explicit conversions between numbers and strings.  There are no explicit conversions between numbers and strings.
 To force an expression to be treated as a number add 0 to it;  To force an expression to be treated as a number add 0 to it;
 to force it to be treated as a string concatenate  to force it to be treated as a string concatenate
 \&\f(CW""\fP to it.  .Li \&""
 .br  to it.
   .Pp
 The scope rules for variables in functions are a botch;  The scope rules for variables in functions are a botch;
 the syntax is worse.  the syntax is worse.
   .Sh HISTORY
   AT&T
   .Nm
   by B. W. Kernighan was updated for
   .Bx 4.4
   and again in 1996.

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.7