lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


>A question related to file parsing that drive me nut :(
>
>hddtemp is a tool that is monitoring disk temperature.
>
>With only 1 disk, it expose following string :
>    "|/dev/sda|WDC WD5000AAKB-00H8A0|29|C|"
>
>and I've been successfully able to parse it with following code :
>
>    local mnt,tp,temp,unit = string.match( s,
>"|(/dev/%a+)|(%a.+)|(%d+)|(%a)")
>
>But with more disk, the string become :
>    "|/dev/sda|IBM-ESXSDTN073C1UCDY10F|28|C||/dev/sdb|WDC
>WD3200AAJB-00J3A0|43|C||/dev/sdc|Maxtor
>34098H4|UNK|*||/dev/sdd|???|ERR|*||/dev/sde|???|ERR|*|"
>
>where sda and sdb are disk whom the temperature can be requested.
>sdc is present on the system but it doesn't support temperature query
>(too old).
>sdd and sde aren't present at the moment.
>
>I would like to iterate against disk exposing their temperature (other
>can be ignored) but
>    for mnt,tp,temp,unit in s:gmatch("|(/dev/%a+)|(%a.+)|(%d+)|(%a)|") do
>        print(mnt, tp)
>    end
>miserably fails
>    /dev/sda    IBM-ESXSDTN073C1UCDY10F|28|C||/dev/sdb|WDC WD3200AAJB-00J3A0
>    nil
>so it is confused when reading first disk name.

Your 1st capture is too "hungry".

>Any idea to parse such strings, being able to iterate b/w each disks
>whatever the string contains 1 or more disks ?

match by device, then unroll per-device captures:

 for part in s:gmatch("(/dev/[^/]+)") do
	for mnt,tp,temp,unit in part:gmatch("([^|]+)|([^|]+)|([^|]+)|([^|]+)") do
		print(mnt, tp, temp, unit)
	end
 end

Not pretty, but regexes rarely are :) Also a fancy-looking regex doesn't equate speed.

Again, I doubt functions like these will end up relevant bottlenecks. You should probably focus on crash-resistance first, f.ex. count the # of "|" to confirm it's formatted as expected before piping it into a regex extractor.

cheers,

-- p