In v5.20, -F implies -a implies -n

Perl was once known for its one-liners in its sysadmin heydays. People would pass around lists of these one liners, many of which replaced complicated pipelines that glued together various unix utilities to do some impressive system maintenance.


  • -a splits the input line on whitespace and puts the result in @F
  • -n adds while( <> ) { ... }
  • The -F specifies what -a should split on

You could write a program to read a line, split on whitespace, and print the elements:

while( <> ) {
	@F = split;
	print "@F\n";
	}

As a one-liner, that program is much sorter:

$ perl -a -ne 'print "@F\n"'

If you want to change the split pattern, you use -F. For instance, you have a line with fields separated by colons:

cat:bird:dog:lizard:fox

You use -F to set the colon as the split pattern:

% perl -aF: -ne 'print "@F\n"'

Prior to v5.20, you had to specify each of those switches, even though they implied each other. The -F switch only makes sense with -a, and -a needs something to put data into $_, hence -n.

$ perl5.20 -F: -le 'print join "=", @F' input.txt

(The -l adds the newline after the print.)

If you don’t need the -F, the -a still implies the -n:

$ perl5.20 -ale 'print join "=", @F' input.txt

You can see what a one-liner does by deparsing it (Use B::Deparse to see what perl thinks the code is):

$ perl5.20 -MO=Deparse -F: -le 'print join "=", @F' input.txt

The code comments I added myself:

BEGIN { $/ = "\n"; $\ = "\n"; }
LINE: while (defined($_ = )) {     # from -n
    chomp $_;                            # from -n
    our(@F) = split(/:/, $_, 0);         # split from -a, @F from -F
    print join('=', @F);                 # argument to -e
}                                        # from -n

To make this new feature work reliably, you have to ensure that you are using at least v5.20. If someone tries your shortened one-liner with an earlier version, it won’t work. That’s the danger with using the new features in any version. Specifying the version negates the saved typing since it also requires you to declare @F since declaring a minimum version also turns on strict since v5.12.

$ perl -M5.20.0 -Mvars=@F -lne 'print join "=", @F' input.txt

Further Reading