Text Processing and One-Liners
20.1 Classic Text-Processing Tasks
use v5.36;
# Word frequency
my %freq;
while (my $line = <>) {
$freq{lc $1}++ while $line =~ /(\w+)/g;
}
for my $w (sort { $freq{$b} <=> $freq{$a} || $a cmp $b } keys %freq) {
printf "%-15s %5d\n", $w, $freq{$w};
}
# Parse an Apache/Nginx access log
my $log_re = qr/^(\S+) \S+ \S+ \[([^\]]+)\] "(\w+) (\S+) [^"]*" (\d{3}) (\d+|-)/;
my (%status, %ip);
while (<>) {
next unless my ($client, $time, $method, $path, $code, $bytes) = /$log_re/;
$status{$code}++;
$ip{$client}++;
}
# Paragraph mode and record-based reading
{
local $/ = ''; # paragraph mode: records separated by blank lines
while (my $para = <$fh>) { ... }
}
{
local $/ = "\n//\n"; # custom record separator (e.g., GenBank records)
}20.2 One-Liners Cookbook
BEGIN { } and END { } blocks run before/after the implicit loop: perl -ne 'BEGIN { $t = 0 } $t += (split)[1]; END { print $t }'.
perl -ne 'print if /ERROR/' app.log # grep
perl -ne 'print unless /^\s*(#|$)/' config.ini # strip comments and blank lines
perl -pe 's/foo/bar/g' input.txt # sed
perl -i.bak -pe 's/\r\n/\n/' *.txt # in-place: convert CRLF to LF, keep backups
perl -lane 'print $F[2]' data.txt # awk '{print $3}'
perl -F, -lane 'print $F[0] if $F[3] > 100' data.csv # custom field separator
perl -lne '$s += $_; END { print $s }' numbers.txt # sum a column
perl -ne '$c++ if /pattern/; END { print "$c\n" }' file # count matches
perl -lne 'print length' file # line lengths
perl -ne 'print if 10..20' file # lines 10 to 20 (flip-flop operator)
perl -ne 'print if /START/../END/' file # lines between markers
perl -nle 'print if !$seen{$_}++' file # unique lines, preserving order
perl -e 'print reverse <>' file # tac
perl -00 -ne 'print if /keyword/' file # paragraph grep
perl -0777 -pe 's/\n\s+/ /g' file # slurp and join continuation lines
perl -MList::Util=sum -lane 'print sum @F' file # sum fields per
…