2006-04-29
Another little script: field
In the footsteps of the first little script, here's
something I call field
:
#!/bin/sh fn="" for i in "$@"; do nf='$'$i if [ -z "$fn" ]; then fn="$nf" else fn="$fn, $nf" fi done exec awk "{print $fn}"
(The exec
is another way around the Linux bash issue.)
You give it one or more field numbers, whereupon it reads standard input
and prints just those fields to standard output. I wrote it because I
got tired of typing 'awk "{print $7}"
' and the like all the time.
Given field
and howmany
, we can now write
what I'll call countup
:
#!/bin/sh field "$@" | howmany
Typical usage is things like 'countup 1 </var/log/web-xfers | sed 10q
'
to show me the top 10 IPs for today's web requests. (Today the big
source is our internal Google search appliance. Although the third
most active source was 200.55.156.97, poking us for security holes.
Badly, which is the most annoying thing about it.)
(An ongoing index for all of my little scripts is here.)
Sidebar: an irritation
The irritating bit about field
is all of the work it has to go through
to generate the print instructions for awk. It feels like there should be
a nice short Perl equivalent, but the closest I've come is the not quite
correct:
#!/usr/bin/perl -w use strict; my @l; while (<STDIN>) { chomp; @l = split; print join(" ", map {$l[$_]} @ARGV), "\n"; }
If you give this a field that doesn't exist in (some or all) records, you get complaints about 'use of uninitialized variable in ...'.
(There are more complicated constructs that will stop this, but I am interested in something compact, no larger than the Bourne shell script, and my Perl is sufficiently rusty that I can't see one right now.)