LshalOutputParser

Problem Specification

10:50 <Thanatermesis> i want to obtain the model of the disk, for example, on a lshal result, you can see your hard disk on "block.device", and in other place (of the same section-device) you see "storage.model" what i want to obtain 10:51 <Thanatermesis> lshal shows a lot of "sections", one per device, i have think to use awk in a way that the field separator be every line, and the record separator could be every "block" of this (so, every section)

Code

BEGIN {
	skip    = 1
	inBlock = 0
	FS = " = "
}

function die(msg) {
	printf "ERROR on line %d of input: %s\n", NR, msg >> "/dev/stderr"
	exit 1
}

function trim(str) {
	sub(/^ +/, "", str)
	sub(/ +$/, "", str)
	return str
}

function startBlock() {
	split("", PROPERTIES) # delete all values in the PROPERTIES array
	split("", PROPORDER)  # clear the ordered properties list
	PROPNUM = 0           # reset the order counter
	split("", PROPTYPES)  # clear the type annotations as well
	parseBlockLine()
}

function parseBlockLine(	key, val, type) {
	key = trim($1)
	match($2, /\([^\)]+\)$/) # find parenthesized strings that are last on the line
	if (RLENGTH > 0) {
		type = substr($2, RSTART+1, RLENGTH-2) # offsets to remove parentheses
		val  = trim(substr($2, 1, (length($2) - RLENGTH))) # remove type info
	} else {
		type = "udi"
		val  = trim($2)
	}
	#printf "!%s! ---- !%s! ---- !%s!\n", key, val, type
	PROPERTIES[key] = PROPORDER[PROPNUM++] = val
	PROPTYPES[key]  = PROPTYPES[PROPNUM]   = type
}

function endBlock() {
	if ("block.storage_device" in PROPERTIES && \
	    "storage.model"        in PROPERTIES && \
	    length(PROPERTIES["storage.model"]) > 2) {
		printf "device:\t%s\nmodel:\t%s\n", 
		  PROPERTIES["block.storage_device"],
		  PROPERTIES["storage.model"]
	}
	return
}

##########################################
# parser code below
##########################################

$0 ~ /^(-+$|Dumped)/ {skip = ! skip; next}
skip {next}
# skip the header and the footer 

/^udi/ && (! inBlock) {
	inBlock = 1
	startBlock()
	next
}
/^  / && inBlock {
	parseBlockLine()
	next
}
/^$/ && inBlock {
	inBlock = 0
	endBlock()
	next
}

(/^udi/ && inBlock) || (/^  / && (! inBlock)) {
	die("Block info line encountered out of sequence, parsing error!")
}

Sample Output

$ lshal | gawk -f ./lshal-parse
device: '/org/freedesktop/Hal/devices/storage_serial_NLB9T3413AVB'
model:  'FUJITSU MHS2040AT'
device: '/org/freedesktop/Hal/devices/storage_model_Slimtype_COMBO_LSC_24081'
model:  'Slimtype COMBO LSC-24081'
$