I learned a fun new perl one-liner today:
perl -00pe0 foo >bar
What does it do? Well, it’s nearly the same as cp foo bar
, except
that it squeezes multiple blank lines into foo
into a single blank
line in bar
.
How does it do that? Well, let’s break it down piece by piece.
Perl’s -0
flag lets you change perl’s “input record separator”.
This lets you fiddle with perl’s idea of what a “line” is. Normally
perl reads in text a line at a time, where a “line” is a string of
text terminated by a newline character. But when you set the -0
flag to 0
, perl will keep reading until it hits a string of 2 or
more newlines in a row. In other words, perl will read in text a
paragraph at a time, and stop when it hits a blank line. If there are
multiple blank lines, perl will treat them as if there was just a
single blank line and throw away the extras. (You can also do the
same thing by setting perl’s special $/ variable to “”.)
The next flag is -p
. That tells perl to read in text a “line” at a
time, execute some code against each line, and then print the line to
standard output. Of course, because of the -00
right before it,
each “line” is actually a paragraph.
The final flag is -e
. This tells perl that the following parameter
is a program that it should execute after it reads in each line.
Normally this is given in between single quotes, but here the entire
program is simply “0”. This is a perl idiom for a no-op. This is
because we don’t need any additional code — the combination of
the -00
and -p
flags are all we need.
Incidentally, blank lines can be squeezed much simply, and with far
less obfuscation, by running cat(1) with the -s
flag:
cat -s foo bar