eax
(fath|lead|hack)er

Perl Powers

Perl can replace awk, sed, and grep for most cases, specifically when a multiline regular expressions is needed. For further help with this article, perl -help is your friend.

Note common Perl sigils used in this article (@: arrays/lists). For deeper understanding: sudo apt -y install perl-doc (if Debian-based distros) or sudo yum -y install perl-Pod-Perldoc (RHEL-based). Then run perldoc perlvar

Common one-liner flags

  • a split the src text into @F array (part of the -F flag)
  • e single line expression
  • i in place replacement (a la sed)
  • F split the src text using a delim (a la Awk’s fields)
  • l new line separator (’\n’ by default)
  • p print the result & execute on each line

grep replacement

echo -e "foo\nfoo bar" | perl -ne 'print if /^foo$/'

sed replacement

echo -e "foo\nbar foo" | perl -pe 's/^f(oo)/\1/'

If you want in-place replacement:

echo foo bar > foo
perl -p -i -e 's/foo/bar/' foo

awk replacement

(Perl’s -F is analogous to the one in awk (field separator))

cat /etc/passwd | perl -F: -lane 'print @F[0], " --- ", @F[1]'

Quick breakdown of what’s happening here:

-lane: line separate, array it, execute on each newline & run the expression

-F          => is delimiting by the colon
print @F[0] => grabs the first column in the @F array and prints it
" --- "     => self-explanatory
@F[1]       => grabs the second column and prints it

multiline regex

echo -e "foo\nfoo bar\nfoo bar\nfoo"  | \
perl -e 'undef $/; $s = <>; while ($s =~ /(bar\nfoo)/g) { print "$1\n"; }'

Quick breakdown of what’s happening here:

Because this is a multiline regex, we have to backtrack, and because of that, the whole file is read entirely into memory, vice streaming per lines. Therefore, we have to undefine the default input record separator (which is newline and Perl uses the magic variable of $/ for that). Then use another one of Perl’s magic operator (<> STDIN) and stores it in a variable that we’ll call $s forSTDIN.

After that, it’s all downhill, get a global modifier (g) on the end of our regex and do the matching inside the while loop expression. Doing this multiline regex with Unix utilities is a pain in the rear.

Fin

From now on, if complex regular expressions are what the problem calls for: do it in Perl! Just kidding, use the tool that you’re most proficient and comfortable with.

Reference

https://www.manning.com/books/minimal-perl

Back to top