Alex Rivera | Logout

What is your latest useful Perl one-liner (or a pipe involving Perl)?

Asked 2008-09-21T19:43:29.250
16

The one-liner should:

  • solve a real-world problem
  • not be extensively cryptic (should be easy to understand and reproduce)
  • be worth the time it takes to write it (should not be too clever)

I'm looking for practical tips and tricks (complementary examples for perldoc perlrun).

Edit
Report

7 Answers

13

Squid log files. They're great, aren't they? Except by default they have seconds-from-the-epoch as the time field. Here's a one-liner that reads from a squid log file and converts the time into a human readable date:

perl -pe's/([\d.]+)/localtime $1/e;' access.log

With a small tweak, you can make it only display lines with a keyword you're interested in. The following watches for stackoverflow.com accesses and prints only those lines, with a human readable date. To make it more useful, I'm giving it the output of tail -f, so I can see accesses in real time:

tail -f access.log | perl -ne's/([\d.]+)/localtime $1/e,print if /stackoverflow\.com/'
answered 2008-09-22T00:13:44.500
8

All one-liners from the answers collected in one place:

  • perl -pe's/([\d.]+)/localtime $1/e;' access.log

  • ack $(ls t/lib/TestPM/|awk -F'.' '{print $1}'|xargs perl -e 'print join "|" => @ARGV') aggtests/ t -l

  • perl -e'while(<*.avi>) { s/avi$/srt/; rename <*.srt>, $_ }'

  • find . -name '*.whatever' | perl -lne unlink

  • tail -F /var/log/squid/access.log | perl -ane 'BEGIN{$|++} $F[6] =~ m{\Qrad.live.com/ADSAdClient31.dll} && printf "%02d:%02d:%02d %15s %9d\n", sub{reverse @_[0..2]}->(localtime $F[0]), @F[2,4]'

  • export PATH=$(perl -F: -ane'print join q/:/, grep { !$c{$_}++ } @F'<<<$PATH)

  • alias e2d="perl -le \"print scalar(localtime($ARGV[0]));\""

  • perl -ple '$_=eval'

  • perl -00 -ne 'print sort split /^/'

  • perl -pe'1while+s/\t/" "x(8-pos()%8)/e'

  • tail -f log | perl -ne '$s=time() unless $s; $n=time(); $d=$n-$s; if ($d>=2) { print qq ($. lines in last $d secs, rate ),$./$d,qq(\n); $. =0; $s=$n; }'

  • perl -MFile::Spec -e 'print join(qq(\n),File::Spec->path).qq(\n)'

See corresponding answers for their descriptions.

answered 2009-02-03T18:26:48.130
6

The Perl one-liner I use the most is the Perl calculator

perl -ple '$_=eval'
answered 2008-10-01T22:33:34.990
4

One of the biggest bandwidth hogs at $work is download web advertising, so I'm looking at the low-hanging fruit waiting to be picked. I've got rid of Google ads, now I have Microsoft in my line of sights. So I run a tail on the log file, and pick out the lines of interest:

tail -F /var/log/squid/access.log | \
perl -ane 'BEGIN{$|++} $F[6] =~ m{\Qrad.live.com/ADSAdClient31.dll}
    && printf "%02d:%02d:%02d %15s %9d\n",
        sub{reverse @_[0..2]}->(localtime $F[0]), @F[2,4]'

What the Perl pipe does is to begin by setting autoflush to true, so that any that is acted upon is printed out immediately. Otherwise the output it chunked up and one receives a batch of lines when the output buffer fills. The -a switch splits each input line on white space, and saves the results in the array @F (functionality inspired by awk's capacity to split input records into its $1, $2, $3... variables).

It checks whether the 7th field in the line contains the URI we seek (using \Q to save us the pain of escaping uninteresting metacharacters). If a match is found, it pretty-prints the time, the source IP and the number of bytes returned from the remote site.

The time is obtained by taking the epoch time in the first field and using 'localtime' to break it down into its components (hour, minute, second, day, month, year). It takes a slice of the first three elements returns, second, minute and hour, and reverses the order to get hour, minute and second. This is returned as a three element array, along with a slice of the third (IP address) and fifth (size) from the original @F array. These five arguments are passed to sprintf which formats the results.

answered 2008-09-22T07:41:54.127
3

I often need to see a readable version of the PATH while shell scripting. The following one-liners print every path entry on its own line.

Over time this one-liner has evolved through several phases:

Unix (version 1):

perl -e 'print join("\n",split(":",$ENV{"PATH"}))."\n"'

Windows (version 2):

perl -e "print join(qq(\n),split(';',$ENV{'PATH'})).qq(\n)"

Both Unix/Windows (using q/qq tip from @j-f-sebastian) (version 3):

perl -MFile::Spec -e 'print join(qq(\n), File::Spec->path).qq(\n)' # Unix
perl -MFile::Spec -e "print join(qq(\n), File::Spec->path).qq(\n)" # Windows
answered 2011-01-27T15:46:49.727
2

Get human-readable output from du, sorted by size:

perl -e '%h=map{/.\s/;7x(ord$&&10)+$`,$_}`du -h`;print@h{sort%h}'
answered 2009-09-17T18:56:27.290
2

Network administrators have the tendency to misconfigure "subnet address" as "host address" especially while using Cisco ASDM auto-suggest. This straightforward one-liner scans the configuration files for any such configuration errors.

incorrect usage: permit host 10.1.1.0

correct usage: permit 10.1.1.0 255.255.255.0

perl -ne "print if /host ([\w\-\.]+){3}\.0 /" *.conf

This was tested and used on Windows, please suggest if it should be modified in any way for correct usage.

answered 2011-05-15T08:46:35.193

Your Answer