diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2017-07-02 17:36:37 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2017-07-02 22:57:07 +1200 |
commit | 95276f25769a0607cda50041169197d0522b98ff (patch) | |
tree | 3a4738901390c94f76de6ee7b6394d39b4c1ed00 /bin | |
parent | Coerce seed to number (diff) | |
download | dotfiles-95276f25769a0607cda50041169197d0522b98ff.tar.gz dotfiles-95276f25769a0607cda50041169197d0522b98ff.zip |
Lots of cleanup of awk scripts
Mostly inspired by suggestions from gawk --lint
Diffstat (limited to 'bin')
-rw-r--r-- | bin/csmw.awk | 1 | ||||
-rw-r--r-- | bin/ddup.awk | 6 | ||||
-rw-r--r-- | bin/gwp.awk | 11 | ||||
-rw-r--r-- | bin/hms.awk | 16 | ||||
-rw-r--r-- | bin/max.awk | 6 | ||||
-rw-r--r-- | bin/mean.awk | 3 | ||||
-rw-r--r-- | bin/med.awk | 10 | ||||
-rw-r--r-- | bin/mftl.awk | 10 | ||||
-rw-r--r-- | bin/mi5.awk | 19 | ||||
-rw-r--r-- | bin/rndi.awk | 35 | ||||
-rw-r--r-- | bin/rndl.awk | 8 | ||||
-rw-r--r-- | bin/sec.awk | 18 | ||||
-rw-r--r-- | bin/tot.awk | 1 | ||||
-rw-r--r-- | bin/trs.awk | 6 | ||||
-rw-r--r-- | bin/unf.awk | 2 | ||||
-rw-r--r-- | bin/xrq.awk | 9 |
16 files changed, 117 insertions, 44 deletions
diff --git a/bin/csmw.awk b/bin/csmw.awk index 4479d8f8..351fc749 100644 --- a/bin/csmw.awk +++ b/bin/csmw.awk @@ -1,4 +1,5 @@ # Print an English comma-separated list of monospace-quoted words (backticks) +BEGIN { wc = 0 } { for (i = 1; i <= NF; i++) ws[++wc] = "`" $i "`" diff --git a/bin/ddup.awk b/bin/ddup.awk index 2dec1d00..63381cfb 100644 --- a/bin/ddup.awk +++ b/bin/ddup.awk @@ -1,2 +1,6 @@ # Skip duplicate lines (without requiring sorted input) -!seen[$0]++ +$0 in seen { next } +length($0) { + seen[$0] = 1 + print +} diff --git a/bin/gwp.awk b/bin/gwp.awk index f1e3b3bd..6b558388 100644 --- a/bin/gwp.awk +++ b/bin/gwp.awk @@ -7,6 +7,9 @@ BEGIN { # Words are separated by any non-alphanumeric characters FS = "[^a-zA-Z0-9]+" + # Nothing found yet + found = 0 + # First argument is the word required; push its case downward so we can # match case-insensitively word = tolower(ARGV[1]) @@ -15,15 +18,17 @@ BEGIN { ARGV[1] = "" # Bail out if we don't have a suitable word - if (!word) + if (!length(word)) fail("Need a single non-null alphanumeric string as a search word") if (word ~ FS) fail("Word contains non-alphanumeric characters; use grep(1)") } # Bailout function -function fail(str) { - printf "%s: %s\n", self, str | "cat >&2" +function fail(msg) { + stderr = "cat >&2" + printf "%s: %s\n", self, msg | stderr + close(stderr) exit(2) } diff --git a/bin/hms.awk b/bin/hms.awk index 3054db44..2aa492a1 100644 --- a/bin/hms.awk +++ b/bin/hms.awk @@ -1,19 +1,23 @@ # Convert seconds to colon-delimited durations BEGIN { OFS = ":" + ex = 0 + stderr = "" } # Refuse to deal with anything that's not a positive (unsigned) integer /[^0-9]/ { - print "hms: Bad number" | "cat >&2" - err = 1 + if (!stderr) + stderr = "cat >&2" + print "hms: Bad number" | stderr + ex = 1 next } # Integer looks valid { # Break it down into hours, minutes, and seconds - s = $0 + s = int($0 + 0) h = int(s / 3600) s %= 3600 m = int(s / 60) @@ -29,4 +33,8 @@ BEGIN { } # Done, exit 1 if we had any errors on the way -END { exit(err > 0) } +END { + if (stderr) + close(stderr) + exit(ex) +} diff --git a/bin/max.awk b/bin/max.awk index 11d4efd9..f6b84ead 100644 --- a/bin/max.awk +++ b/bin/max.awk @@ -1,8 +1,6 @@ # Get the maximum of a list of numbers -{ - if (NR == 1 || $1 > max) - max = $1 -} +BEGIN { max = 0 } +NR == 1 || $1 > max { max = $1 + 0 } END { if (!NR) exit(1) diff --git a/bin/mean.awk b/bin/mean.awk index b34dc111..98060389 100644 --- a/bin/mean.awk +++ b/bin/mean.awk @@ -1,5 +1,6 @@ # Get the mean of a list of numbers -{ tot += $1 } +BEGIN { tot = 0 } +{ tot += $1 + 0 } END { # Error out if we read no values at all if (!NR) diff --git a/bin/med.awk b/bin/med.awk index aee120cb..0f4d6086 100644 --- a/bin/med.awk +++ b/bin/med.awk @@ -1,7 +1,13 @@ # Get the median of a list of numbers +BEGIN { + self = "med" + stderr = "cat >&2" +} { vals[NR] = $1 } NR > 1 && vals[NR] < vals[NR-1] && !warn++ { - printf "med: Input not sorted!\n" | "cat >&2" + if (!stderr) + stderr = "cat >&2" + printf "%s: Input not sorted!\n", self | stderr } END { # Error out if we read no values at all @@ -12,6 +18,8 @@ END { else med = (vals[NR/2] + vals[NR/2+1]) / 2 print med + if (stderr) + close(stderr) if (warn) exit(1) } diff --git a/bin/mftl.awk b/bin/mftl.awk index 21976337..1546526d 100644 --- a/bin/mftl.awk +++ b/bin/mftl.awk @@ -31,6 +31,12 @@ BEGIN { FS = "[ \t:]" } # Print unique determined targets, sorted END { - for (t in ats) - print t | "sort" + sort = "" + for (t in ats) { + if (!sort) + sort = "sort" + print t | sort + } + if (sort) + close(sort) } diff --git a/bin/mi5.awk b/bin/mi5.awk index 48d71657..7acb6f3b 100644 --- a/bin/mi5.awk +++ b/bin/mi5.awk @@ -4,19 +4,14 @@ BEGIN { # You can change any of these, but while changing these is still relatively # sane... - if (!length(open)) - open = "<%" - if (!length(shut)) - shut = "%>" + open = "<%" + shut = "%>" # ... changing these probably isn't, and should compel you to rethink your # code, or quite possibly your entire life thus far. - if (!length(quote)) - quote = "`" - if (!length(unquote)) - unquote = "'" - if (!length(dnl)) - dnl = "dnl" + quote = "`" + unquote = "'" + dnl = "dnl" # We do not start in a block bmac = 0 @@ -24,7 +19,9 @@ BEGIN { # Fatal error function function fatal(str) { - printf "%s: %s\n", self, str | "cat >&2" + stderr = "cat >&2" + printf "%s: %s\n", self, str | stderr + close(stderr) exit(1) } diff --git a/bin/rndi.awk b/bin/rndi.awk index 49df4398..07c69bc7 100644 --- a/bin/rndi.awk +++ b/bin/rndi.awk @@ -1,20 +1,41 @@ # Get a low-quality random number between two integers. Depending on the awk -# implementation, if you don't provide a third argument (a seed), you might get -# very predictable random numbers based on the current epoch second. +# implementation, if you don't have rnds(1df) available to generate a seed of +# sufficient quality, you might get very predictable random numbers based on +# the current epoch second. BEGIN { + self = "rndi" - # Seed with the third argument if given - if (ARGV[3]) - srand(ARGV[3]) + # Check we have two arguments + if (ARGC != 3) + fail("Need a lower and upper bound") - # If not, just seed with what is probably a date/time-derived value + # Floor args and check for sanity + lower = int(ARGV[1] + 0) + upper = int(ARGV[2] + 0) + if (lower >= upper) + fail("Bounds must be numeric, first lower than second") + + # Seed the random number generator + rnds = "rnds 2>/dev/null" + rnds | getline seed + close(rnds) + if (length(seed)) + srand(seed + 0) else srand() # Print a random integer bounded by the first and second arguments - print int(ARGV[1] + rand() * (ARGV[2] - ARGV[1] + 1)) + print int(lower + rand() * (upper - lower + 1)) # Bail before processing any lines exit } + +# Bailout function +function fail(str) { + stderr = "cat >&2" + printf "%s: %s\n", self, str | stderr + close(stderr) + exit(2) +} diff --git a/bin/rndl.awk b/bin/rndl.awk index 8feb4f90..925235ee 100644 --- a/bin/rndl.awk +++ b/bin/rndl.awk @@ -7,7 +7,9 @@ BEGIN { self = "rndl" # Seed the random number generator - "rnds 2>/dev/null" | getline seed + rnds = "rnds 2>/dev/null" + rnds | getline seed + close(rnds) if (length(seed)) srand(seed + 0) else @@ -23,7 +25,9 @@ END { # Check that we processed at least one line if (!NR) { - printf "%s: No lines found on input\n", self | "cat >&2" + stderr = "cat >&2" + printf "%s: No lines found on input\n", self | stderr + close(stderr) exit(1) } diff --git a/bin/sec.awk b/bin/sec.awk index 001b017d..645df147 100644 --- a/bin/sec.awk +++ b/bin/sec.awk @@ -1,13 +1,19 @@ # Convert [[[hh:]mm:]ss] timestamps to seconds # Separator is :, strip out leading zeroes -BEGIN { FS = ":0*" } +BEGIN { + FS = ":0*" + stderr = "" + ex = 0 +} # If no fields, too many fields, or illegal characters, warn, skip line, accrue # errors !NF || NF > 3 || /[^0-9:]/ { - print "sec: Bad format" | "cat >&2" - err = 1 + if (!stderr) + stderr = "cat >&2" + print "sec: Bad format" | stderr + ex = 1 next } @@ -21,4 +27,8 @@ NF == 2 { printf "%u\n", $1 * 60 + $2 } NF == 1 { printf "%u\n", $1 } # Done, exit 1 if we had any errors on the way -END { exit(err > 0) } +END { + if (stderr) + close(stderr) + exit(ex) +} diff --git a/bin/tot.awk b/bin/tot.awk index eda25724..add5f00e 100644 --- a/bin/tot.awk +++ b/bin/tot.awk @@ -1,3 +1,4 @@ # Total a list of numbers +BEGIN { tot = 0 } { tot += $1 } END { print tot } diff --git a/bin/trs.awk b/bin/trs.awk index 58fdf8a9..fbb7eeba 100644 --- a/bin/trs.awk +++ b/bin/trs.awk @@ -18,8 +18,10 @@ BEGIN { } # Bailout function -function fail(str) { - printf "%s: %s\n", self, str | "cat >&2" +function fail(msg) { + stderr = "cat >&2" + printf "%s: %s\n", self, msg | stderr + close(stderr) exit(2) } diff --git a/bin/unf.awk b/bin/unf.awk index ac6172f7..7acb09c2 100644 --- a/bin/unf.awk +++ b/bin/unf.awk @@ -1,5 +1,7 @@ # Unfold header lines in an internet message, don't touch the body +BEGIN { buf = "" } + # Function to write and empty the buffer function wrbuf() { if (length(buf)) diff --git a/bin/xrq.awk b/bin/xrq.awk index 686cf677..62253bdb 100644 --- a/bin/xrq.awk +++ b/bin/xrq.awk @@ -8,12 +8,16 @@ BEGIN { # Check we have at least one resource name if (ARGC < 2) { - print "xrq: Need at least one resource name" | "cat >&2" + stderr = "cat >&2" + print "xrq: Need at least one resource name" | stderr + close(stderr) exit(2) } # Run `xrdb -query` and search for instances of the requested resource - while ("xrdb -query" | getline) { + xrdb = "xrdb -query" + found = 0 + while (xrdb | getline) { for (i in ARGV) { if ($1 == ARGV[i]) { found = 1 @@ -21,6 +25,7 @@ BEGIN { } } } + close(xrdb) # Exit successfully if we found at least one result exit(!found) |