📄 perl.ms
字号:
.fiArray literals are denoted by separating individual values by commas, andenclosing the list in parentheses:.nf (LIST).fiIn a context not requiring an array value, the value of the array literalis the value of the final element, as in the C comma operator.For example,.nf.ne 4 @foo = (\'cc\', \'\-E\', $bar);assigns the entire array value to array foo, but $foo = (\'cc\', \'\-E\', $bar);.fiassigns the value of variable bar to variable foo.Note that the value of an actual array in a scalar context is the lengthof the array; the following assigns to $foo the value 3:.nf.ne 2 @foo = (\'cc\', \'\-E\', $bar); $foo = @foo; # $foo gets 3.fiYou may have an optional comma before the closing parenthesis of anarray literal, so that you can say:.nf @foo = ( 1, 2, 3, );.fiWhen a LIST is evaluated, each element of the list is evaluated inan array context, and the resulting array value is interpolated into LISTjust as if each individual element were a member of LIST. Thus arrayslose their identity in a LIST\*(--the list (@foo,@bar,&SomeSub)contains all the elements of @foo followed by all the elements of @bar,followed by all the elements returned by the subroutine named SomeSub..PPA list value may also be subscripted like a normal array.Examples:.nf $time = (stat($file))[8]; # stat returns array value $digit = ('a','b','c','d','e','f')[$digit-10]; return (pop(@foo),pop(@foo))[0];.fi.PPArray lists may be assigned to if and only if each element of the listis an lvalue:.nf ($a, $b, $c) = (1, 2, 3); ($map{\'red\'}, $map{\'blue\'}, $map{\'green\'}) = (0x00f, 0x0f0, 0xf00);The final element may be an array or an associative array: ($a, $b, @rest) = split; local($a, $b, %rest) = @_;.fiYou can actually put an array anywhere in the list, but the first arrayin the list will soak up all the values, and anything after it will geta null value.This may be useful in a local()..PPAn associative array literal contains pairs of values to be interpretedas a key and a value:.nf.ne 2 # same as map assignment above %map = ('red',0x00f,'blue',0x0f0,'green',0xf00);.fiArray assignment in a scalar context returns the number of elementsproduced by the expression on the right side of the assignment:.nf $x = (($foo,$bar) = (3,2,1)); # set $x to 3, not 2.fi.PPThere are several other pseudo-literals that you should know about.If a string is enclosed by backticks (grave accents), it first undergoesvariable substitution just like a double quoted string.It is then interpreted as a command, and the output of that commandis the value of the pseudo-literal, like in a shell.In a scalar context, a single string consisting of all the output isreturned.In an array context, an array of values is returned, one for each lineof output.(You can set $/ to use a different line terminator.)The command is executed each time the pseudo-literal is evaluated.The status value of the command is returned in $? (see Predefined Namesfor the interpretation of $?).Unlike in \f2csh\f1, no translation is done on the returndata\*(--newlines remain newlines.Unlike in any of the shells, single quotes do not hide variable namesin the command from interpretation.To pass a $ through to the shell you need to hide it with a backslash..PPEvaluating a filehandle in angle brackets yields the next linefrom that file (newline included, so it's never false until EOF, atwhich time an undefined value is returned).Ordinarily you must assign that value to a variable,but there is one situation where an automatic assignment happens.If (and only if) the input symbol is the only thing inside the conditional of a.I whileloop, the value isautomatically assigned to the variable \*(L"$_\*(R".(This may seem like an odd thing to you, but you'll use the constructin almost every.I perlscript you write.)Anyway, the following lines are equivalent to each other:.nf.ne 5 while ($_ = <STDIN>) { print; } while (<STDIN>) { print; } for (\|;\|<STDIN>;\|) { print; } print while $_ = <STDIN>; print while <STDIN>;.fiThe filehandles.IR STDIN ,.I STDOUTand.I STDERRare predefined.(The filehandles.IR stdin ,.I stdoutand.I stderrwill also work except in packages, where they would be interpreted aslocal identifiers rather than global.)Additional filehandles may be created with the.I openfunction..PPIf a <FILEHANDLE> is used in a context that is looking for an array, an arrayconsisting of all the input lines is returned, one line per array element.It's easy to make a LARGE data space this way, so use with care..PPThe null filehandle <> is special and can be used to emulate the behavior of\fIsed\fR and \fIawk\fR.Input from <> comes either from standard input, or from each file listed onthe command line.Here's how it works: the first time <> is evaluated, the ARGV array is checked,and if it is null, $ARGV[0] is set to \'-\', which when opened gives you standardinput.The ARGV array is then processed as a list of filenames.The loop.nf.ne 3 while (<>) { .\|.\|. # code for each line }.ne 10is equivalent to the following Perl-like pseudo code: unshift(@ARGV, \'\-\') \|if \|$#ARGV < $[; while ($ARGV = shift) { open(ARGV, $ARGV); while (<ARGV>) { .\|.\|. # code for each line } }.fiexcept that it isn't as cumbersome to say, and will actually work.It really does shift array ARGV and put the current filename intovariable ARGV.It also uses filehandle ARGV internally\*(--<> is just a synonym for<ARGV>, which is magical.(The pseudo code above doesn't work because it treats <ARGV> as non-magical.).PPYou can modify @ARGV before the first <> as long as the array ends upcontaining the list of filenames you really want.Line numbers ($.) continue as if the input was one big happy file.(But see example under eof for how to reset line numbers on each file.).PP.ne 5If you want to set @ARGV to your own list of files, go right ahead.If you want to pass switches into your script, you canput a loop on the front like this:.nf.ne 10 while ($_ = $ARGV[0], /\|^\-/\|) { shift; last if /\|^\-\|\-$\|/\|; /\|^\-D\|(.*\|)/ \|&& \|($debug = $1); /\|^\-v\|/ \|&& \|$verbose++; .\|.\|. # other switches } while (<>) { .\|.\|. # code for each line }.fiThe <> symbol will return FALSE only once.If you call it again after this it will assume you are processing another@ARGV list, and if you haven't set @ARGV, will input from.IR STDIN ..PPIf the string inside the angle brackets is a reference to a scalar variable(e.g. <$foo>),then that variable contains the name of the filehandle to input from..PPIf the string inside angle brackets is not a filehandle, it is interpretedas a filename pattern to be globbed, and either an array of filenames or thenext filename in the list is returned, depending on context.One level of $ interpretation is done first, but you can't say <$foo>because that's an indirect filehandle as explained in the previousparagraph.You could insert curly brackets to force interpretation as afilename glob: <${foo}>.Example:.nf.ne 3 while (<*.c>) { chmod 0644, $_; }is equivalent to.ne 5 open(foo, "echo *.c | tr \-s \' \et\er\ef\' \'\e\e012\e\e012\e\e012\e\e012\'|"); while (<foo>) { chop; chmod 0644, $_; }.fiIn fact, it's currently implemented that way.(Which means it will not work on filenames with spaces in them unlessyou have /bin/csh on your machine.)Of course, the shortest way to do the above is:.nf chmod 0644, <*.c>;.fi.Sh "Syntax"A.I perlscript consists of a sequence of declarations and commands.The only things that need to be declared in.I perlare report formats and subroutines.See the sections below for more information on those declarations.All uninitialized user-created objects are assumed tostart with a null or 0 value until theyare defined by some explicit operation such as assignment.The sequence of commands is executed just once, unlike in.I sedand.I awkscripts, where the sequence of commands is executed for each input line.While this means that you must explicitly loop over the lines of your input file(or files), it also means you have much more control over which files and whichlines you look at.(Actually, I'm lying\*(--it is possible to do an implicit loop with either the.B \-nor.B \-pswitch.).PPA declaration can be put anywhere a command can, but has no effect on theexecution of the primary sequence of commands\*(--declarations all take effectat compile time.Typically all the declarations are put at the beginning or the end of the script..PP.I Perlis, for the most part, a free-form language.(The only exception to this is format declarations, for fairly obvious reasons.)Comments are indicated by the # character, and extend to the end of the line.If you attempt to use /* */ C comments, it will be interpreted either asdivision or pattern matching, depending on the context.So don't do that..Sh "Compound statements"In.IR perl ,a sequence of commands may be treated as one command by enclosing itin curly brackets.We will call this a BLOCK..PPThe following compound commands may be used to control flow:.nf.ne 4 if (EXPR) BLOCK if (EXPR) BLOCK else BLOCK if (EXPR) BLOCK elsif (EXPR) BLOCK .\|.\|. else BLOCK LABEL while (EXPR) BLOCK LABEL while (EXPR) BLOCK continue BLOCK LABEL for (EXPR; EXPR; EXPR) BLOCK LABEL foreach VAR (ARRAY) BLOCK LABEL BLOCK continue BLOCK.fiNote that, unlike C and Pascal, these are defined in terms of BLOCKs, notstatements.This means that the curly brackets are \fIrequired\fR\*(--no dangling statements allowed.If you want to write conditionals without curly brackets there are severalother ways to do it.The following all do the same thing:.nf.ne 5 if (!open(foo)) { die "Can't open $foo: $!"; } die "Can't open $foo: $!" unless open(foo); open(foo) || die "Can't open $foo: $!"; # foo or bust! open(foo) ? \'hi mom\' : die "Can't open $foo: $!"; # a bit exotic, that last one.fi.PPThe.I ifstatement is straightforward.Since BLOCKs are always bounded by curly brackets, there is never anyambiguity about which.I ifan.I elsegoes with.If you use.I unlessin place of.IR if ,the sense of the test is reversed..PPThe.I whilestatement executes the block as long as the expression is true(does not evaluate to the null string or 0).The LABEL is optional, and if present, consists of an identifier followed bya colon.The LABEL identifies the loop for the loop control statements.IR next ,.IR last ,and.I redo(see below).If there is a.I continueBLOCK, it is always executed just beforethe conditional is about to be evaluated again, similarly to the third partof a.I forloop in C.Thus it can be used to increment a loop variable, even when the loop hasbeen continued via the.I nextstatement (similar to the C \*(L"continue\*(R" statement)..PPIf the word.I whileis replaced by the word.IR until ,the sense of the test is reversed, but the conditional is still tested beforethe first iteration..PPIn either the.I ifor the.I whilestatement, you may replace \*(L"(EXPR)\*(R" with a BLOCK, and the conditionalis true if the value of the last command in that block is true..PPThe.I forloop works exactly like the corresponding.I whileloop:.nf.ne 12 for ($i = 1; $i < 10; $i++) { .\|.\|. }is the same as $i = 1; while ($i < 10) { .\|.\|. } continue { $i++; }.fi
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -