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
…