I perform remote operations on a series of servers. Rather than maintain the server list in several scripts, I consolidated it into a single file called servers.txt Exciting! The second I did that, I raised my own bar. You’d expect a config file parser to omit comments and blank lines, right? I do.
The anticipated time to write that parser was longer than I expected. In order to save you time, dear reader, I decided to post it here. This sh script reads a file into an array while skipping comment lines and blanks.
Here’s a sample config file:
# # Comment line # Wed Feb 25 19:28:54 EST 2014 homer.joedog.org marge.joedog.org
bart.joedog.org lisa.joedog.org
burns.joedog.org # EOF
And here’s a script to parse it:
#!/bin/sh
let X=0 while read line ; do if [[ ! $line =~ [^[:space:]] ]] ; then continue fi [ -z "`echo $line | grep '^#'`" ] || continue SRV[$X]=$line let X=$X+1 done < servers.txt
for (( i=0; i<${#SRV[@]}; i++ )); do echo ${SRV[$i]} done
Here’s the output from the script:
$ sh ./haha homer.joedog.org marge.joedog.org bart.joedog.org lisa.joedog.org burns.joedog.org
Here’s another way to coax the data out of the $SRV array. You can convert it into a space separated string and loop through it in a traditional manner:
SRV=${SRV[@]} for S in $SRV ; do echo $S done
After you guys vet this in the comments, I’ll add it to the sh scripting cheat sheet. Happy hacking.
UPDATE: A reader sends me a one-liner which implements similar functionality. If you don’t require an indexed array, then it’s only drawback is its perl dependency.
SRV=$(egrep '[^[:space:]$]' servers.txt|egrep -v '^#'|perl -pe 's/^s+//') for S in $SRV ; do echo $S done