📄 ch19_01.htm
字号:
You can even put backup copies of the original files into anotherdirectory (provided that the directory already exists):<blockquote><pre class="programlisting"><tt class="computeroutput">%</tt> <tt class="userinput"><b>perl -pi'old/*.orig' -e 's/foo/bar/' xyx</b></tt> # backup to 'old/xyx.orig'</pre></blockquote>These pairs of one-liners are equivalent:<blockquote><pre class="programlisting"><tt class="computeroutput">%</tt> <tt class="userinput"><b>perl -pi -e 's/foo/bar/' xyx</b></tt> # overwrite current file<tt class="computeroutput">%</tt> <tt class="userinput"><b>perl -pi'*' -e 's/foo/bar/' xyx</b></tt> # overwrite current file<tt class="computeroutput">%</tt> <tt class="userinput"><b>perl -pi'.orig' -e 's/foo/bar/' xyx</b></tt> # backup to 'xyx.orig'<tt class="computeroutput">%</tt> <tt class="userinput"><b>perl -pi'*.orig' -e 's/foo/bar/' xyx</b></tt> # backup to 'xyx.orig'</pre></blockquote>From the shell, saying:<blockquote><pre class="programlisting"><tt class="computeroutput">%</tt> <tt class="userinput"><b>perl -p -i.orig -e "s/foo/bar/;"</b></tt></pre></blockquote>is the same as using the program:<blockquote><pre class="programlisting">#!/usr/bin/perl -pi.origs/foo/bar/;</pre></blockquote>which is convenient shorthand for the remarkably longer:<blockquote><pre class="programlisting">#!/usr/bin/perl$extension = '.orig';LINE: while (<>) { if ($ARGV ne $oldargv) { if ($extension !~ /\*/) { $backup = $ARGV . $extension; } else { ($backup = $extension) =~ s/\*/$ARGV/g; } unless (rename($ARGV, $backup)) { warn "cannot rename $ARGV to $backup: $!\n"; close ARGV; next; } open(ARGVOUT, ">$ARGV"); select(ARGVOUT); $oldargv = $ARGV; } s/foo/bar/;}continue { print; # this prints to original filename}select(STDOUT);</pre></blockquote><a name="INDEX-3411"></a><a name="INDEX-3412"></a>This long code is virtually identical to the simple one-liner with the<span class="option">-i</span> switch, except that the <span class="option">-i</span> formdoesn't need to compare <tt class="literal">$ARGV</tt> to<tt class="literal">$oldargv</tt> to know when the filename has changed. Itdoes, however, use <tt class="literal">ARGVOUT</tt> for the selectedfilehandle and restore the old <tt class="literal">STDOUT</tt> as thedefault output filehandle after the loop. Like the code above, Perlcreates the backup file irrespective of whether any output has trulychanged. See the description of the <tt class="literal">eof</tt> functionfor examples ofhow to use use <tt class="literal">eof</tt> withoutparentheses to locate the end of each input file, in case you want toappend to each file or to reset line numbering.</p><p>If, for a given file, Perl is unable to create the backup file asspecified in the <em class="replaceable">EXTENSION</em>, it will issue awarning to that effect and continue processing any other remainingfiles listed.</p><p>You cannot use <span class="option">-i</span> to create directories or to stripextensions from files. Nor can you use it with a <tt class="literal">~</tt>to indicate a home directory--which is just as well, since some folkslike to use that character for their backup files:<blockquote><pre class="programlisting"><tt class="computeroutput">%</tt> <tt class="userinput"><b>perl -pi~ -e 's/foo/bar/' file1 file2 file3...</b></tt></pre></blockquote>Finally, the <span class="option">-i</span> switch does not stop Perl fromrunning if no filenames are given on the command line. When thishappens, no backup is made since the original file cannot bedetermined, and processing proceeds from <tt class="literal">STDIN</tt> to<tt class="literal">STDOUT</tt> as might be expected.</p></dd><dt><b><span class="option">-I</span><em class="replaceable">DIRECTORY</em></b></dt><dd><p><a name="INDEX-3413"></a><a name="INDEX-3414"></a><a name="INDEX-3415"></a><a name="INDEX-3416"></a><a name="INDEX-3417"></a>Directories specified by <span class="option">-I</span> are prepended to <tt class="literal">@INC</tt>, which holdsthe search path for modules. <span class="option">-I</span> also tells the C preprocessorwhere to search for include files. The C preprocessor is invokedwith <span class="option">-P</span>; by default it searches <em class="emphasis">/usr/include</em> and <em class="emphasis">/usr/lib/perl</em>.Unless you're going to be using the C preprocessor (and almost noone does any more), you're better off using the <tt class="literal">use lib</tt> directivewithin your script. Like <tt class="literal">use lib</tt>, however, the <span class="option">-I</span> switchimplicitly adds platform-specific directories. See <tt class="literal">use lib</tt> in<a href="ch31_01.htm">Chapter 31, "Pragmatic Modules"</a>, for details.</p></dd><dt><b><span class="option">-l</span><em class="replaceable">OCTNUM</em></b></dt><dt><b><span class="option">-l</span></b></dt><dd><p><a name="INDEX-3418"></a><a name="INDEX-3419"></a><a name="INDEX-3420"></a><a name="INDEX-3421"></a><a name="INDEX-3422"></a>Enables automatic line-end processing. It has two effects: first, itautomatically <tt class="literal">chomp</tt>s the line terminator when used with <span class="option">-n</span> or<span class="option">-p</span>, and second, it sets <tt class="literal">$\</tt> to the value of <em class="replaceable">OCTNUM</em> so that any printstatements will have a line terminator of ASCII value <em class="replaceable">OCTNUM</em> addedback on. If <em class="replaceable">OCTNUM</em> is omitted, <span class="option">-l</span>sets <tt class="literal">$\</tt> to the current value of<tt class="literal">$/</tt>, typically newline. So, to trim lines to 80 columns, say this:<blockquote><pre class="programlisting"><tt class="computeroutput">%</tt> <tt class="userinput"><b>perl -lpe 'substr($_, 80) = ""'</b></tt></pre></blockquote>Note that the assignment <tt class="literal">$\ = $/</tt> is done when the switch isprocessed, so the input record separator can be different from theoutput record separator if the <span class="option">-l</span> switch is followed by a <span class="option">-0</span>switch:<blockquote><pre class="programlisting"><tt class="computeroutput">%</tt> <tt class="userinput"><b>gnufind / -print0 | perl -ln0e 'print "found $_" if -p'</b></tt></pre></blockquote>This sets <tt class="literal">$\</tt> to newline and later sets <tt class="literal">$/</tt> to the null character.(Note that <tt class="literal">0</tt> would have been interpreted as part of the <span class="option">-l</span> switchhad it followed the <span class="option">-l</span> directly. That's why we bundled the <span class="option">-n</span>switch between them.)</p></dd><dt><b><span class="option">-m</span> and <span class="option">-M</span></b></dt><dd><p>These switches load a <em class="replaceable">MODULE</em> as if you'd executed a <tt class="literal">use</tt>, unlessyou specify <span class="option">-</span><em class="replaceable">MODULE</em> instead of <em class="replaceable">MODULE</em>, in which case theyinvoke <tt class="literal">no</tt>. For example, <span class="option">-Mstrict</span> is like <tt class="literal">use strict</tt>, while<span class="option">-M-strict</span> is like <tt class="literal">no strict</tt>.</p><dl><dt><b><span class="option">-m</span><em class="replaceable">MODULE</em></b></dt><dd><p><a name="INDEX-3423"></a><a name="INDEX-3424"></a><a name="INDEX-3425"></a><a name="INDEX-3426"></a><a name="INDEX-3427"></a>Executes <tt class="literal">use</tt><em class="replaceable">MODULE</em><tt class="literal">()</tt> before executing your script.</p></dd><dt><b><span class="option">-M</span><em class="replaceable">MODULE</em></b></dt><dt><b><span class="option">-M'</span><em class="replaceable">MODULE</em> <span class="option">...'</span></b></dt><dd><p>Executes <tt class="literal">use</tt><em class="replaceable">MODULE</em>before executing your script. The command is formed by mereinterpolation of the rest of the argument after the<span class="option">-M</span>, so you can use quotes to add extra code after themodule name, for example, <span class="option">-M'MODULE qw(foo bar)'</span>.</p></dd><dt><b><span class="option">-M</span><em class="replaceable">MODULE</em><span class="option">=</span><em class="replaceable">arg1</em><span class="option">,</span><em class="replaceable">arg2</em><span class="option">...</span></b></dt><dd><p>A little built-in syntactic sugar means you can also say<tt class="userinput"><b>-Mmodule=foo,bar</b></tt> as a shortcut for<tt class="userinput"><b>-M'module qw(foo bar)'</b></tt>. This avoids the needto use quotes when importing symbols. The actual code generated by<tt class="userinput"><b>-Mmodule=foo,bar</b></tt> is:<blockquote><pre class="programlisting">use module split(/,/, q{foo,bar})</pre></blockquote>Note that the <tt class="literal">=</tt> form removes the distinctionbetween <span class="option">-m</span> and <span class="option">-M</span>, but it's betterto use the uppercase form to avoid confusion.</p></dd></dl><p>You may only use the <span class="option">-M</span> and <span class="option">-m</span>switches from a real command-line invocation of Perl, not as optionspicked up on the <tt class="literal">#!</tt> line. (Hey, if you're gonnaput it in the file, why not just write the equivalent<tt class="literal">use</tt> or <tt class="literal">no</tt> instead?)</p></dd><dt><b><span class="option">-n</span></b></dt><dd><p><a name="INDEX-3428"></a><a name="INDEX-3429"></a>Causes Perl to assume the following loop around your script, which makesit iterate over filename arguments much as <em class="emphasis">sed -n</em> or <em class="emphasis">awk</em> do:<blockquote><pre class="programlisting">LINE:while (<>) { ... # your script goes here}</pre></blockquote>You may use <tt class="literal">LINE</tt> as a loop label from within youscript, even though you can't see the actual label in your file.</p><p>Note that the lines are not printed by default. See<span class="option">-p</span> to have lines printed. Here is an efficient wayto delete all files older than a week:<blockquote><pre class="programlisting">find . -mtime +7 -print | perl -nle unlink</pre></blockquote>This is faster than using the <em class="emphasis">-exec</em> switch of<em class="emphasis">find</em>(1) because you don't have to start aprocess on every filename found. By an amazing coincidence,<tt class="literal">BEGIN</tt> and <tt class="literal">END</tt> blocks may be usedto capture control before or after the implicit loop, just as in<em class="emphasis">awk</em>.</p></dd><dt><b><span class="option">-p</span></b></dt><dd><p><a name="INDEX-3430"></a><a name="INDEX-3431"></a>Causes Perl to assume the following loop around your script, which makesit iterate over filename arguments much as <em class="emphasis">sed</em> does:<blockquote><pre class="programlisting">LINE:while (<>) { ... # your script goes here}continue { print or die "-p destination: $!\n";}</pre></blockquote>You may use <tt class="literal">LINE</tt> as a loop label from within youscript, even though you can't see the actual label in your file.</p><p>If a file named by an argument cannot be opened for some reason, Perlwarns you about it, and moves on to the next file. Note that thelines are printed automatically. An error occurring during printingis treated as fatal. By yet another amazing coincidence,<tt class="literal">BEGIN</tt> and <tt class="literal">END</tt> blocks may be usedto capture control before or after the implicit loop, just as in<em class="emphasis">awk</em>.</p></dd><dt><b><span class="option">-P</span></b></dt><dd><p><a name="INDEX-3432"></a><a name="INDEX-3433"></a><a name="INDEX-3434"></a>Causes your script to be run through the C preprocessor beforecompilation by Perl. (Since both comments and<em class="emphasis">cpp</em>(1) directives begin with the<tt class="literal">#</tt> character, you should avoid starting commentswith any words recognized by the C preprocessor such as"<tt class="literal">if</tt>", "<tt class="literal">else</tt>" or"<tt class="literal">define</tt>".) Whether you use <span class="option">-P</span>switch or not, Perl still pays attention to <tt class="literal">#line</tt>directives to control the line number and filename, so anypreprocessor can apprise Perl of these things. See the section<a href="ch24_05.htm#ch24-sect-gen">Section 19.5.2, "Generating Perl in Other Languages"</a> in <a href="ch24_01.htm">Chapter 24, "Common Practices"</a>.</p></dd><dt><b><span class="option">-s</span></b></dt><dd><p><a name="INDEX-3435"></a><a name="INDEX-3436"></a>Enables rudimentary switch-parsing for switches on the command lineafter the script name but before any filename arguments or a"<span class="option">--</span>" switch-processing terminator. Anyswitch found is removed from <tt class="literal">@ARGV</tt>, and a variableby the same name as the switch is set in Perl. Switch bundling is notallowed because multicharacter switches are permitted.</p><p>The following script prints "<tt class="literal">true</tt>" only when thescript is invoked with a <tt class="literal">-foo</tt> switch.<blockquote><pre class="programlisting">#!/usr/bin/perl -sif ($foo) { print "true\n" }</pre></blockquote>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -