Great! Now, I've learnt something new. I've used sed
for all sorts of (minor) substitutions, and not realized you can actually program in it. Obviously a quite weak "machine", since it has only two registers, and a rather obscure language.
Since sed
doesn't take input variables, I've mad it an sh
script that invokes sed
with a dynamic program, which is prepared by replacing BLOCK and ENTRY with the actual tags from the command line. That replacement is done with a separate simple sed
substitution to prepare the specific program to achieve the entry insertion.
The following script seems to do the work. If called addentry
, it would be invoked as
$ addentry LETTER SAMPLE < data
to reproduce the input data with the entry inserted as its output. I suppose there's an -i
option to sed
for "in-place editing", if needs be.
#!/bin/sh
/bin/sed -n "$(cat << EOF | sed -e "s/BLOCK/$1/g;s/ENTRY/$2/g"
# Initialize hold space with 0
1 { x ; /^$/ s/^$/0/; x }
# Lines outside the interesting block are just printed
/\s*serverClass:BLOCK/,/^$/! { p }
# Lines of the interesting block are considered more in detail
/\s*serverClass:BLOCK/,/^$/ {
# The final empty line is replaced by the new entry, using the line
# counter from the "hold buffer"
/^$/ { g; s/\(.*\)/whitelist.\1=ENTRY/p; s/.*//p; b xx }
# print the line
p
# Jump forward for the block leader (note xx is a label)
/serverClass:/ { b xx }
# Increment hold space counter
# (Only handles 0-9 here; room for improvement)
x; y/0123456789/1234567890/; h
# If the block ends the file without blank line, then add the
# new entry at end.
$ { g; s/\(.*\)/whitelist.\1=ENTRY/p; b xx }
# Label xx is here
:xx
}
EOF
)"
Many thanks for raising this (for me) interesting challenge.