sh Script: Read lines and omit comments and blanks

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

And here’s a script to parse it:

let X=0
while read line ; do
  if [[ ! $line =~ [^[:space:]] ]] ; then
  [ -z "`echo $line | grep '^#'`" ] || continue
  let X=$X+1
done < servers.txt
for (( i=0; i<${#SRV[@]}; i++ )); do
  echo ${SRV[$i]}

Here’s the output from the script:

$ sh ./haha

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:

for S in $SRV ; do
  echo $S

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
Posted in Programming, sh | Leave a comment

Recent Comments

  • Oleg: Hm, i have the same problem as “Gokul Muralidharan says: July 27, 2012 at 1:00 pm” He says “I...
  • Jeff: Oleg, Because you told it to run just one repetition: -r1 I think what you’re looking for is...
  • Oleg: I think, i have found one bug. The command siege -d10 -r1 -c25 -f url.txt hits ONLY FIRST url. Why?
  • Jeff Fulmer: The hit counts will vary since you’re doing time-based testing. Instead of -t10s try -r10 siege...
  • Oleg: Strange results. For example i do siege -t 10s -v -c 10 and count of hits always...