📄 unx15.htm
字号:
<BR></P>
<PRE>$2==0 {
print ""
print ""
print ""
}</PRE>
<P>When the second field of the input file is equal to 0, awk prints three blank lines to the output file.
<BR></P>
<HR ALIGN=CENTER>
<NOTE>
<IMG SRC="note.gif" WIDTH = 35 HEIGHT = 35><B>NOTE:</B> Notice that print "" prints a blank line to the output file, whereas the statement print alone prints the current input line.
<BR></NOTE>
<HR ALIGN=CENTER>
<P>When you look at an awk program file, you may also find commentary within. Anything typed from a # to the end of the line is considered a comment and is ignored by awk. They are notes to anyone reading the program to explain what is going on in words,
not computerese.
<BR></P>
<H4 ALIGN="CENTER">
<CENTER><A ID="I18" NAME="I18">
<FONT SIZE=3><B>A Note on </B><B><I>awk</I></B><B> Error Messages</B>
<BR></FONT></A></CENTER></H4>
<P>Awk error messages (when they appear) tend to be cryptic. Often, due to the brevity of the program, a typo is easily found. Not all errors are as obvious; I have scattered some examples of errors throughout this chapter.
<BR></P>
<H3 ALIGN="CENTER">
<CENTER><A ID="I19" NAME="I19">
<FONT SIZE=4><B>Print Selected Fields</B>
<BR></FONT></A></CENTER></H3>
<P>Awk<B> </B>includes three ways to specify printing. The first is implied. A pattern without an action assumes that the action is to print. The two ways of actively commanding awk to print are print and printf(). For now, I am going to stick to using
only implied printing and the print statement. printf is discussed in a later section ("Input/Output") and is used mainly for precise output. This section demonstrates the first two types of printing through some step-by-step examples.
<BR></P>
<H4 ALIGN="CENTER">
<CENTER><A ID="I20" NAME="I20">
<FONT SIZE=3><B>Program Components</B>
<BR></FONT></A></CENTER></H4>
<P>If I want to be sure the System Administrator spelled my name correctly in the /etc/password file, I enter an awk command to find a match but omit an action. The following command line puts a list on-screen.
<BR></P>
<PRE>$ awk '/Ann/' /etc/passwd
amarshal:oPWwC9qVWI/ps:2005:12:Ann Marshall:/usr/grad/amarshal:/bin/csh
andhs26:0TFnZSVwcua3Y:2488:23:DeAnn O'Neal:/usr/lstudent/andhs26:/bin/csh
alewis:VYfz4EatT4OoA:2623:22:Annie Lewis:/usr/lteach/alewis:/bin/csh
cmcintyr:0FciKEDDMkauU:2630:22:Carol Ann McIntyre:/usr/lteach/cmcintyr:/bin/csh
jflanaga:ShrMnyDwLI/mM:2654:22:JoAnn Flanagan:/usr/lteach/jflanaga:/bin/csh
lschultz:mic35ZiFj9zWk:3060:22:Lee Ann Schultz, :/usr/lteach/lschultz:/bin/csh
akestle:job57Lb5/ofoE:3063:22:Ann Kestle.:/usr/lteach/akestle:/bin/csh
bakehs59:yRYV6BtcW7wFg:3075:23:DeAnna Adlington, Baker :/usr/bakehs59:/bin/csh
ahernan:AZZPQNCkw6ffs:3144:23:Ann Hernandez:/usr/lstudent/ahernan:/bin/csh
$ _</PRE>
<P>I look on the monitor and see the correct spelling.
<BR></P>
<HR ALIGN=CENTER>
<NOTE>
<IMG SRC="note.gif" WIDTH = 35 HEIGHT = 35><B>ERROR NOTE:</B> For the sake of making a point, suppose I had chosen the pattern /Anne/. A quick glance above shows that there would be no matches. Entering awk '/Anne/' /etc/passwd will therefore produce
nothing but another system prompt to the monitor. This can be confusing if you expect output. The same goes the other way; above, I wanted the name Ann, but the names LeAnn, Annie and DeAnna matched, too. Sometimes choosing a pattern too long or too short
can cause an unneeded headache.
<BR></NOTE>
<HR ALIGN=CENTER>
<HR ALIGN=CENTER>
<NOTE>
<IMG SRC="imp.gif" WIDTH = 68 HEIGHT = 35><B>TIP:</B> If a pattern match is not found, look for a typo in the pattern you are trying to match.
<BR></NOTE>
<HR ALIGN=CENTER>
<P>Printing specified fields of an ASCII (plain text) file is a straightforward awk task. Because this program example is so short, only the input is in a file. The first input file, "sales", is a file of car sales by month. The file consists of
each salesperson's name, followed by a monthly sales figure. The end field is a running total of that person's total sales.
<BR></P>
<H5 ALIGN="CENTER">
<CENTER><A ID="I21" NAME="I21">
<FONT SIZE=3><B>The Input File and Program</B>
<BR></FONT></A></CENTER></H5>
<PRE>$cat sales
John Anderson,12,23,7,42
Joe Turner,10,25,15,50
Susan Greco,15,13,18,46
Bob Burmeister,8,21,17,46</PRE>
<P>The following command line prints the salesperson's name and the total sales for the first quarter.
<BR></P>
<PRE>awk -F, '{print $1,$5}' sales
John Anderson 42
Joe Turner 50
Susan Greco 46
Bob Burmeister 46</PRE>
<P>A comma (,) between field variables indicates that I want OFS applied between output fields as shown in a previous example. Remember without the comma, no field separator will be used, and the displayed output fields (or output file) will all run
together.
<BR></P>
<HR ALIGN=CENTER>
<NOTE>
<IMG SRC="imp.gif" WIDTH = 68 HEIGHT = 35><B>TIP: </B>Putting two field separators in a row inside a print statement creates a syntax error with the print statement; however, using the same field twice in a single print statement is valid syntax. For
example:
<BR>
<BR>awk '{print($1,$1)'
<BR></NOTE>
<HR ALIGN=CENTER>
<H3 ALIGN="CENTER">
<CENTER><A ID="I22" NAME="I22">
<FONT SIZE=4><B>Patterns</B>
<BR></FONT></A></CENTER></H3>
<P>A pattern is the first half of an awk program statement. In awk there are six accepted pattern types. This section discusses each of the six in detail. You have already seen a couple of them, including BEGIN, and a specified, slash-delimited pattern, in
use. Awk has many string matching capabilities arising from patterns, and the use of regular expressions in patterns. A range pattern locates a sequence. All patterns except range patterns may be combined in a compound pattern.
<BR></P>
<P>I began the chapter by saying awk was a pattern-match and process language. This section explores exactly what is meant by a pattern match. As you'll see, what kind pattern you can match depends on exactly how you're using the awk pattern specification
notation.
<BR></P>
<H4 ALIGN="CENTER">
<CENTER><A ID="I23" NAME="I23">
<FONT SIZE=3><B>BEGIN and END</B>
<BR></FONT></A></CENTER></H4>
<P>The two special patterns BEGIN and END may be used to indicate a match, either before the first input record is read, or after the last input record is read, respectively. Some versions of awk require that, if used, BEGIN must be the first pattern of
the program and, if used, END must be the last pattern of the program. While not necessarily a requirement, it is nonetheless an excellent habit to get into, so I encourage you to do so, as I do throughout this chapter. Using the BEGIN pattern for
initializing variables is common (although variables can be passed from the command line to the program too; see "Command Line Arguments") The END pattern is used for things which are input-dependent such as totals.
<BR></P>
<P>If I want to know how many lines are in a given program, I type the following line:
<BR></P>
<PRE><B>$awk 'END {print _Total lines: _$NR}' myprogram</B></PRE>
<P>I see Total lines: 256 on the monitor and therefore know that the file myprogram has 256 lines. At any point while awk is processing the file, the variable NR counts the number of records read so far. NR at the end of a file has a value equal to the
number of lines in the file.
<BR></P>
<P>How might you see a BEGIN block in use? Your first thought might be to initialize variables, but if it's a numeric value, it's automatically initialized to zero before its first use. Instead, perhaps you're building a table of data and want to have some
columnar headings. With this in mind, here's a simple awk script that shows you all the accounts that people named Dave have on your computer:
<BR></P>
<PRE>BEGIN {
FS=_:_ # remember that the passwd file uses colons
OFS=_ _ # we_re setting the output to a TAB
print _Account_,_Username_
}
/Dav/ {print $1, $5}</PRE>
<P>Here's what it looks like in action (we've called this file _daves.awk_, though the program matches Dave and David, of course):
<BR></P>
<PRE>$ awk -f daves.awk /etc/passwd
Account Username
andrews Dave Andrews
d3 David Douglas Dunlap
daves Dave Smith
taylor Dave Taylor</PRE>
<P>Note that you could also easily have a summary of the total number of matched accounts by adding a variable that's incremented for each match, then in the END block output in some manner. Here's one way to do it:
<BR></P>
<PRE>BEGIN { FS=_:_ ; OFS=_ _ # input colon separated, output tab separated
print _Account_,_Username_
}
/Dav/ {print $1, $5 ; matches++ }
END { print _A total of _matches_ matches._}</PRE>
<P>Here you can see how awk allows you to shorten the length of programs by having multiple items on a single line, particularly useful for initialization. Also notice the C increment notation: _matches++_ is functionally identical to _matches = matches +
1_. Finally, also notice that we didn't have to initialize the variable _matches_ to zero since it was done for us automatically by the awk system.
<BR></P>
<H4 ALIGN="CENTER">
<CENTER><A ID="I24" NAME="I24">
<FONT SIZE=3><B>Expressions</B>
<BR></FONT></A></CENTER></H4>
<P>Any expression may be used with any operator in awk. An expression consists of any operator in awk, and its corresponding operand in the form of a pattern-match statement. Type conversion—variables being interpreted as numbers at one point, but
strings at another—is automatic, but never explicit. The type of operand needed is decided by the operator type. If a numeric operator is given a string operand, it is converted and vice versa.
<BR></P>
<HR ALIGN=CENTER>
<NOTE>
<IMG SRC="imp.gif" WIDTH = 68 HEIGHT = 35><B>TIP:</B> To force a conversion, if the desired change is string to number, add (+) 0. If you wish to explicitly convert a number to a string concatenate "" (the null string) to the variable. Two quick
examples: num=3; num=num __ creates a new numeric variable and sets it to the number three, then by appending a null string to it, translates it to a string (e.g., the string with the character 3 within). Adding zero to that string — num=num + 0
— forces it back to a numeric value.
<BR></NOTE>
<HR ALIGN=CENTER>
<P>Any expression can be a pattern. If the pattern, in this case the expression, evaluates to a nonzero or nonnull value, then the pattern matches that input record. Patterns often involve comparison. The following are the valid awk comparison operators:
<BR></P>
<UL>
<LH><B>Table 15.1. Comparison Operators in </B><B>awk</B><B>.</B>
<BR></LH></UL>
<TABLE BORDER>
<TR>
<TD>
<PRE><I>Operator</I>
<BR></PRE>
<TD>
<PRE><I>Meaning</I>
<BR></PRE>
<TR>
<TD>
<P>==</P>
<TD>
<P>is equal to</P>
<TR>
<TD>
<P><</P>
<TD>
<P>less than</P>
<TR>
<TD>
<P>></P>
<TD>
<P>greater than</P>
<TR>
<TD>
<P><=</P>
<TD>
<P>less than or equal to</P>
<TR>
<TD>
<P>>=</P>
<TD>
<P>greater than or equal to</P>
<TR>
<TD>
<P>!=</P>
<TD>
<P>not equal to</P>
<TR>
<TD>
<P>~</P>
<TD>
<P>matched by</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -