Skip to content

ruby -n -p -a -F -l -i came from Perl

Level: 101 · anyone who writes shell pipelines

One line: Ruby's command line kept Perl's text-processing switches — -n and -p loop over input lines in $_, -a with -F splits each into $F, -l chomps, -i edits in place — along with $., END {} and a bare regex that tests $_; each Perl one-liner below has a Ruby twin that prints the same thing.

Verified output of one_liner_flags_sh.sh — regenerated by tools/run_examples.py, never hand-typed.

$ ruby -ne 'print if /bob/' users.txt
bob:x:1002:/home/bob
$ perl -ne 'print if /bob/' users.txt
bob:x:1002:/home/bob

$ ruby -F: -lane 'print $F[0]' users.txt
alice
# disabled
bob
$ perl -F: -lane 'print $F[0]' users.txt
alice
# disabled
bob

$ ruby -pe 'sub(/:x:/, ":*:")' users.txt
alice:*:1001:/home/alice
# disabled
bob:*:1002:/home/bob
$ perl -pe 's/:x:/:*:/' users.txt
alice:*:1001:/home/alice
# disabled
bob:*:1002:/home/bob

$ ruby -ne 'print "#{$.}: #{$_}" if /^#/' users.txt
2: # disabled
$ perl -ne 'print "$.: $_" if /^#/' users.txt
2: # disabled

$ ruby -ne '$n = ($n || 0) + 1; END { puts $n }' users.txt
3
$ perl -ne '$n++; END { print "$n\n" }' users.txt
3

$ ruby -i.bak -pe '$_.upcase!' users.txt; ls; head -1 users.txt
users.txt
users.txt.bak
ALICE:X:1001:/HOME/ALICE

The switches

In both Ruby and Perl
-n wrap the program in a loop over every input line, each in $_
-p the same, and print $_ at the end of each pass
-a split each line into the array $F
-F: the separator -a splits on
-l chomp each line as it is read, and end each print with a newline
-i.bak edit the named files in place, keeping .bak copies
$. the number of the current input line
END { } run once, after the last line

Where they differ

  • Substitution. Perl's s/// edits $_ directly. Ruby's -p and -n programs get sub and gsub as plain method calls that act on $_; those methods exist only under -n or -p.
  • Interpolation. Perl interpolates $. into a string as it is; Ruby needs #{$.}.
  • A counter. Perl's $n++ works on a variable that was never set. Ruby needs ($n || 0) + 1, since nil + 1 raises.

The full list of Ruby's switches is on the command-line options page ↗; Perl's are in perlrun ↗.

If you are coming from another language

The Perl library takes the same switches apart from Perl's side: -n and -p are a loop ↗, -l, -a and -F take a line apart ↗ and -i edits in place ↗.

Python has no -n or -p; the Python library's -c is not the prompt ↗ shows what python3 -c does instead. The Encodings library's awk is three programs ↗ covers the tool that both Perl's switches and Ruby's were built to replace.