📄 ch16.htm
字号:
<P>
Multiple parameters are specified using a syntax similar to a
Perl program. For example, consider the following statement:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">#define POW(base, power) ((base) ** (power))
<BR>
$result = POW(2,3);</FONT></TT>
</BLOCKQUOTE>
<P>
It produces this result:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">$result = ((2) ** (3));</FONT></TT>
</BLOCKQUOTE>
<P>
Macros can be reused. For example,
<BLOCKQUOTE>
<TT><FONT FACE="Courier">#define PI 3.141<BR>
#define AREA(rad) (2* (rad) * PI)<BR>
$result = 43 + AREA($radius);</FONT></TT>
</BLOCKQUOTE>
<P>
Here, the macro <TT><FONT FACE="Courier">PI</FONT></TT> is defined
first, the macro <TT><FONT FACE="Courier">AREA</FONT></TT> uses
<TT><FONT FACE="Courier">PI</FONT></TT> to return an area for
a given radius in <TT><FONT FACE="Courier">$</FONT></TT>.
<H3><A NAME="UsingthenandpOptionsforHandling">Using the <TT><FONT SIZE=4 FACE="Courier">-n</FONT></TT><FONT SIZE=4>
and </FONT><TT><FONT SIZE=4 FACE="Courier">-p</FONT></TT><FONT SIZE=4>
Options for Handling Multiple Files</FONT></A></H3>
<P>
When processing input from multiple files, it's often convenient
to put the processing function in a <TT><FONT FACE="Courier">while(<>)</FONT></TT>
loop so that each line in each file is sequentially processed.
For example, you'll see code of the following form:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">while ($line = <>) {<BR>
&processMe($line)<BR>
}</FONT></TT>
</BLOCKQUOTE>
<P>
Use the <TT><FONT FACE="Courier">-n</FONT></TT> option to not
specify the <TT><FONT FACE="Courier">while</FONT></TT> loop. This
option forces Perl to take your program and execute it once for
each line of input in each of the files specified on the command
line. Here's an example:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">#!perl -n<BR>
$line = $_;<BR>
chop ($line);<BR>
printf ("%d %-52s *\n", $ctr++, $line);</FONT></TT>
</BLOCKQUOTE>
<P>
The <TT><FONT FACE="Courier">-n</FONT></TT> option encloses this
program in an invisible <TT><FONT FACE="Courier">while</FONT></TT>
loop. Each line of input is stored in the system variable <TT><FONT FACE="Courier">$_</FONT></TT>
by the Perl interpreter, which then calls this program. The same
program could be rewritten as follows:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">#!perl<BR>
while (<>) {<BR>
$line = $_;<BR>
chop ($line);<BR>
printf ("%d %-52s *\n", $ctr++, $line);<BR>
}</FONT></TT>
</BLOCKQUOTE>
<P>
The <TT><FONT FACE="Courier">-n</FONT></TT> and <TT><FONT FACE="Courier">-e</FONT></TT>
options can be used together to perform a function on each line
of input of all input files. For example, the following statements
both search for the word <TT><FONT FACE="Courier">param</FONT></TT>
in all files whose names end with <TT><FONT FACE="Courier">.pl</FONT></TT>:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">perl -n -e "print $_ if (/param/);"
*.pl<BR>
<BR>
grep "param" *.pl</FONT></TT>
</BLOCKQUOTE>
<P>
The <TT><FONT FACE="Courier">print $_ if (/param/);</FONT></TT>
argument supplied with the <TT><FONT FACE="Courier">-e</FONT></TT>
option is a one-line Perl program that prints the current line
if the word<I> </I><TT><FONT FACE="Courier">param</FONT></TT>
is found in it. The <TT><FONT FACE="Courier">-n</FONT></TT> option
executes the one-line program once for each input line that is
set into the system variable <TT><FONT FACE="Courier">$_</FONT></TT>.
<P>
The <TT><FONT FACE="Courier">-p</FONT></TT> option is like the
<TT><FONT FACE="Courier">-n </FONT></TT>option except that it
prints each line as it reads each line. The <TT><FONT FACE="Courier">-p</FONT></TT>
option is designed for use with the <TT><FONT FACE="Courier">-i</FONT></TT>
option, which is described in the following section. If both the
<TT><FONT FACE="Courier">-p</FONT></TT> and the <TT><FONT FACE="Courier">-n</FONT></TT>
options are specified, the <TT><FONT FACE="Courier">-n</FONT></TT>
option is ignored.
<H3><A NAME="TheiOptiontoEditFiles">The <TT><FONT SIZE=4 FACE="Courier">-i</FONT></TT><FONT SIZE=4>
Option to Edit Files</FONT></A></H3>
<P>
Both the <TT><FONT FACE="Courier">-n</FONT></TT> and <TT><FONT FACE="Courier">-p</FONT></TT>
options read lines from the files whose names are listed on the
command line. When the <TT><FONT FACE="Courier">-i</FONT></TT>
option is used with the <TT><FONT FACE="Courier">-p</FONT></TT>
option, the Perl interpreter takes the input lines being read
and writes them back out to the files from which they came. For
example, consider the following command:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">perl -p -i -e "s/Costa/Rica/g;"
*.txt</FONT></TT>
</BLOCKQUOTE>
<P>
It replaces every instance of <TT><FONT FACE="Courier">Costa</FONT></TT>
with <TT><FONT FACE="Courier">Rica</FONT></TT> in all the files
whose names end with <TT><FONT FACE="Courier">.txt</FONT></TT>.
<P>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR VALIGN=TOP><TD ><B>Caution</B></TD></TR>
<TR VALIGN=TOP><TD >
<BLOCKQUOTE>
Do not use the <TT><FONT FACE="Courier">-i</FONT></TT> option with the <TT><FONT FACE="Courier">-n</FONT></TT> option. The following command:
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">perl -n -i -e "s/Stock/Option/g;" *.txt</FONT></TT>
</BLOCKQUOTE>
<BLOCKQUOTE>
also changes all occurrences of <TT><FONT FACE="Courier">Stock</FONT></TT> to <TT><FONT FACE="Courier">Option</FONT></TT>. However, it does <I>not</I> write out the input lines after it changes them! Because the <TT><FONT FACE="Courier">-i</FONT></TT>
option forces the input files to be written to and nothing is printed, you'll erase the contents of all the files with <TT><FONT FACE="Courier">.txt</FONT></TT> extensions!
</BLOCKQUOTE>
</TD></TR>
</TABLE></CENTER>
<P>
<P>
The <TT><FONT FACE="Courier">-i</FONT></TT> option does not have
to work in conjunction with the <TT><FONT FACE="Courier">-p</FONT></TT>
option if the program that uses the option contains the <TT><FONT FACE="Courier"><></FONT></TT>
operator inside a loop. For example, consider the following command:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">perl -i *.txt</FONT></TT>
</BLOCKQUOTE>
<P>
It will copy the content of each input file to a temporary file
and then open it for reading. The input file is closed and then
reopened for writing. This process is repeated for all input files.
<P>
Listing 16.1 presents a simple example of a program using both
the <TT><FONT FACE="Courier">-i</FONT></TT> option and the <TT><FONT FACE="Courier"><></FONT></TT>
operator. This program replaces all occurrences of <TT><FONT FACE="Courier">Wall</FONT></TT>
with <TT><FONT FACE="Courier">Brick</FONT></TT>.
<HR>
<BLOCKQUOTE>
<B>Listing 16.1. A program that edits files using the </B><TT><B><FONT FACE="Courier">-i</FONT></B></TT><B>
option.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">1 #!perl -I<BR>
2 while ($line = <>) {<BR>
3 $line =~ s/Wall/Brick/g;<BR>
4 print ($line);
<BR>
5 }</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
No output is sent to the screen because the output is redirected
to each input file.
<P>
The <TT><FONT FACE="Courier">-i</FONT></TT> option can be used
to back up input files, too. By specifying a new file extension
to the <TT><FONT FACE="Courier">-i</FONT></TT> option, you can
ask that the new extension be appended to the filename being written
to. For example, the following command:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">perl -i .bak dog mouse</FONT></TT>
</BLOCKQUOTE>
<P>
will result in two extra files, <TT><FONT FACE="Courier">dog.bak</FONT></TT>
and <TT><FONT FACE="Courier">mouse.bak</FONT></TT>, being written
to disk. The <TT><FONT FACE="Courier">.bak</FONT></TT> file extension
specified with <TT><FONT FACE="Courier">-i</FONT></TT> will force
the Perl interpreter to copy each <TT><I><FONT FACE="Courier">file</FONT></I></TT>
to <TT><I><FONT FACE="Courier">file.bak</FONT></I></TT> before
overwriting it.
<H3><A NAME="UsingtheaOption">Using the <TT><FONT SIZE=4 FACE="Courier">-a</FONT></TT><FONT SIZE=4>
Option</FONT></A></H3>
<P>
The <TT><FONT FACE="Courier">-a</FONT></TT> option is used for
extracting words from files. The <TT><FONT FACE="Courier">-a</FONT></TT>
option is designed to be used with the <TT><FONT FACE="Courier">-n</FONT></TT>
or <TT><FONT FACE="Courier">-p</FONT></TT> option to split incoming
lines into a list of items in the <TT><FONT FACE="Courier">@F</FONT></TT>
array. Each item in the <TT><FONT FACE="Courier">@F</FONT></TT>
array is a word derived by applying the <TT><FONT FACE="Courier">split('
',$_)</FONT></TT> function to each input line. For example, if
your input file contains the following line:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">My name is Kamran
</FONT></TT>
</BLOCKQUOTE>
<P>
the result of the <TT><FONT FACE="Courier">-a</FONT></TT> option
that reads this line sets the contents of the array <TT><FONT FACE="Courier">@F</FONT></TT>
to be the following list:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">("My", "name", "is",
"Kamran")</FONT></TT>
</BLOCKQUOTE>
<P>
Note that extraneous spaces and tabs from the input line have
not been added to the <TT><FONT FACE="Courier">@F</FONT></TT>
array.
<P>
Listing 16.2 shows a sample program of how to use the <TT><FONT FACE="Courier">-a</FONT></TT>
option to extract all numeric values that are the first word of
an input line.
<HR>
<BLOCKQUOTE>
<B>Listing 16.2. Sample use of the </B><TT><B><FONT FACE="Courier">-a</FONT></B></TT><B>
option.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">1 #!perl -a -n<BR>
2 while ($F[0] =~ /[^\d.]/) {<BR>
3 shift
(@F);<BR>
4 next
if (!defined($F[0]));<BR>
5 }<BR>
6 print ("$F[0] \n");</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
Note that this program prints every line and prints only the first
word that does not contain a digit or a <TT><FONT FACE="Courier">.</FONT></TT>
character.
<H3><A NAME="UsingtheFOption">Using the <TT><FONT SIZE=4 FACE="Courier">-F</FONT></TT><FONT SIZE=4>
Option</FONT></A></H3>
<P>
The <TT><FONT FACE="Courier">-F</FONT></TT> option is designed
to be used along with the <TT><FONT FACE="Courier">-a</FONT></TT>
option. It is used to specify the pattern to use when splitting
input lines into words. For example, if the input fields on each
line that is input to a program are separated by a colon, you
would use the following statement:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">perl -a -n -F: textfile</FONT></TT>
</BLOCKQUOTE>
<P>
In this case, the words in the input file are assumed to be separated
by a colon. You can use opening and closing slashes as pattern
delimiters. This means that both the following programs do the
same thing:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">prog -a -n -F: *.txt<BR>
<BR>
prog -a -n -F/:/ *.txt</FONT></TT>
</BLOCKQUOTE>
<H3><A NAME="Usingthe0Option">Using the <TT><FONT SIZE=4 FACE="Courier">-0</FONT></TT><FONT SIZE=4>
Option</FONT></A></H3>
<P>
The default end-of-input for one line of text in Perl is the newline.
That is, the Perl interpreter reads a line from an input file
or from the keyboard until it sees a newline character. You can
specify an end-of-line input character other than the newline
character by using the <TT><FONT FACE="Courier">-0<I> OOO</I></FONT></TT>
option. The <TT><FONT FACE="Courier">0</FONT></TT> here is the
digit zero for the option, and the letter <TT><FONT FACE="Courier">O</FONT></TT>
is the octal number to replace the newline character. For example,
the following command:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">perl -0 07 program *.bin</FONT></TT>
</BLOCKQUOTE>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -