You'll notice I'm posting late again, for which I blame C.S. Lewis, and since
he's dead he can't defend himself from this unfounded accusation
completely serious and non-trivial explanation for my tardiness.
As for actually post, I work as a support guy for a Subversion
hosting company. We also host Trac, so
part of my job is occasionally setting up custom ticket
fields for customers. This involves editing the trac.ini, a simple text
file. This is fairly easy when you just have to modify one Trac instance, but
every now and again I have to modify a couple of dozen files. I have tried this
using sed
before, but this is a prime example of the the "When
all you've got is a hammer, every problem is a nail" fallacy. I'd been sort of
interested in learning more about awk
and this seemed
like a prime opportunity to "learn by doing", and now I'll reinforce with
"learning by teaching". So with out further ado here's my short script
interspersed with an explanation of how it works, and a complete copy of the
code at the bottom.
The BEGIN
section is a special section that is run once before
processing the file, it can be used for setting variables, as I have done here.
The i
variable, a more descriptive name would have been good,
stores the state of the script.
if ( i == 0 ) { print }
The {
starts the main awk
script, which is run once
for each line in the file being processed. This first line simply prints out the
input line being examined if i
equals zero, which it does in the
initial state of the program.
{
if ( i == 1 ) {
print "# Ticket Custom Section\n"
i = 2 }
The next section is the else
clause for the preceding
if
clause, which executes it's own if-else pair. The
if
clause executes if i
equals one, which it does if
we have just passed the "[ticket-custom]
" line in the trac.ini
file. This section prints out the required custom ticket definitions and changes
i
to two, which will prevent anything from being written until it
gets to the end of the custom ticket section, see below. You need to change the
print
statement to print the the required ticket custom section of
course; it might be more readable to use a series of individual statements
rather than just one.
}
This next line is executed if i
doesn't equal zero or one,
meaning that we are currently in the custom field section. It's a single short
if
statement that checks if the line being processed
($0
) matches (~
) a regular expression, in this case
/\[.*\]/
. This will match any line that contains a "[" followed by
a series of characters, followed by a "]"; basically a trac.ini section head. So
if it finds the start of a new section in the file it will print it out, and
then set i
back to zero, which means it will just print out the
rest of the lines in the file.
}
Then here's the final line which is a simple if
that is run for each line
in the file and checks if the line is the start of the custom field section
([ticket-custom]
), and if so sets i
to one; the result
of which is show above.
Since the code is probably slightly unclear unless you can see the whole thing here it is:
{
if ( i == 0 ) { print }
else
{
if ( i == 1 ) {
print "# Ticket Custom Section\n"
i = 2 }
else { if ( $0 ~ /\[.*\]/ ) { print ; i = 0 } }
}
if ( $0 == "[ticket-custom]" ) { i = 1 }
}