config

OpenBSD system configuration
git clone git://jacobedwards.org/config
Log | Files | Refs | README

commit b131e501e0f6ecb2914b3f82227f8ff88d6c0855
parent afbd66b19f91bd616c10a489a76c501f4f0390c4
Author: Jacob R. Edwards <n/a>
Date:   Wed, 28 Dec 2022 13:39:17 -0800

Add sr script

This script maintains a table of records (currently always lines)
from files. If the given name is prefixed with a plus ('+') it's
records are added to the table, if it's prefixed with minus ('-'),
records found in it are removed from the table.

At the end, all the records are printed out in the order they were
added to the table.

Diffstat:
Alocal/bin/bin/sr | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 86 insertions(+), 0 deletions(-)

diff --git a/local/bin/bin/sr b/local/bin/bin/sr @@ -0,0 +1,86 @@ +#!/bin/sh +# Copyright 2022 Jacob R. Edwards +# sr -- select records +# +# This script maintains a table of records (currently always lines) +# from files. If the given name is prefixed with a plus ('+') it's +# records are added to the table, if it's prefixed with minus ('-'), +# records found in it are removed from the table. +# +# At the end, all the records are printed out in the order they were +# added to the table. (If a record is already in the table, it is not +# added again, so if the same record was obtained from both 'a' and +# 'b' and it wasn't removed in between, it's position is depended +# solely upon 'a'.) + + +awk 'function die(msg) +{ + status = msg + exit 1 +} + +function usage(msg) +{ + die(sprintf("%s\n%s", msg, "usage: sr (+|-)file [...]")); +} + +function addx(x) +{ + if (! (x in t)) { + t[x] = count++; + } +} + +function subx(x) +{ + if (x in t) + delete t[x]; +} + +function dofile(expr, _, op, file, n, line) +{ + op = substr(expr, 1, 1); + if (!match(op, "^[+-]$")) + usage(op ": Invalid operator"); + + file = substr(expr, 2); + if (!file) + file = "/dev/stdin" + + while ((n = getline line < file) > 0) + op == "+" ? addx(line) : subx(line); + close(file) + if (n < 0) + die(file ": Unable to read file") +} + +BEGIN { + keeporder = 1 + + if (ARGC == 1) + ARGV[ARGC++] = "+" + + for (i = 1; i < ARGC; ++i) + dofile(ARGV[i]); + + if (!keeporder) { + for (i in t) + print(i) + exit 0 + } + + for (i in t) + rt[t[i]] = i + for (i = 0; i < count; ++i) + if (i in rt) + print rt[i]; + exit 0 +} + +END { + if (status) { + print "error: " status > "/dev/stderr" + exit 1 + } +}' "$@"