The -n and -p options wrap your script inside loops. Before looking at specific examples, let's see what the loops look like and how they are changed by the -a and -F options.
The -n option causes Perl to execute your script inside the following loop:
while (<>) { # your script }
The -p option uses the same loop, but adds a continue block so that $_ will be printed every time through the loop. If both -n and -p are specified on the command line, the -p option will take precedence. The loop looks like this:
while (<>) { # your script } continue { print; }
The -a option adds a split() function call to the beginning of each iteration of the loop so that the loop looks like this:
while (<>) { @F = split(/ /); # your script }
The -F option lets you split on something besides the space character. If you used -F/i+/ on the command line, the loop would look like this:
while (<>) { @F = split(/i+/); # your script }
You can use BEGIN and END blocks if you need to specify some initialization or cleanup code. The initialization section might be used to create objects or to open log files. The cleanup section can be used to display statistics or close files. For example,
BEGIN { # initialization section $count = 0; } while (<>) { # your script } END { # cleanup section print("The count was $count.\n"); }
Next, you'll see some examples of these options in action. Let's start with a command line that simply displays each line of the input file-like the type command in DOS and UNIX.
Let the file test.dat contain the following:
David Veterinarian John Orthopedist Jeff Dentist
Then the command line may be formed:
perl -p -e "1;" test.dat
This command line is equivalent to:
while (<>) { 1; } continue { print; }
Note The 1; statement was used to give Perl something to process. Otherwise, Perl would not have had any statements to execute.
And will display:
David Veterinarian John Orthopedist Jeff Dentist
How about just printing the first word of each line? You could use this command line:
perl -p -e "s/\s*(\w+).*/$1/;" test.dat
which is equivalent to:
while (<>) { s/\s*(\w+).*/$1/; } continue { print; }
And will display:
David John Jeff
If you have data files that store information in columns, you can pull out the second column of information like this:
perl -p -e "s/\s*.+\s(.+)\s*/$1\n/;" test.datpar
which will display:
Veterinarian Orthopedist Dentist
You can use the -a option to get access to information stored in columns. For example, you could also display the second column like this:
perl -p -a -e "$_ = \"$F[1]\n\";" test.dat
which is equivalent to
while (<>) { @F = split(/ /); $_ = \"$F[1]\n\"; } continue { print; }
Notice that you need to escape the double-quotes in the above command line. If you don't do this you will get an error message.