Reputation: 966
I have a input text file which I am processing using TCL/tk. The file has several parameters followed by their values. If a value is not available, N/A is printed next to parameter name.
For example,
Temperature : 27 deg C
Current : N/A
Voltage : 200 V
I want to extract the value of each parameter, compare it with N/A and then take some action. So far I have written following code.
set counter 0
set value {split $result ":"}
foreach rec value {
if {counter == 1} {
# Add logic here to confirm if we have value or N/A
}
incr counter 1
}
I want to know if there is a simple or better way to do a cut (bash) like operation to directly get the value of the parameter in TCL/tk?
Upvotes: 0
Views: 190
Reputation: 25980
I am still not completely sure what you are looking for, but I think this is rather idomatic, and I think better than dump reading everything and iterating again (and quite faster than regular expressions):
set fd [open "my_file"]
while { [gets $fd line] > -1 } {
lassign [split $line :] name value
if { [string trim $value] == "N/A" } {
#Something
}
}
close $fd
trim
handles extra spaces after the split. If you are using value more than once I would re-set it about the if
.
Upvotes: 2
Reputation: 137757
I'd use a regular expression to do the line parsing. It's not strictly necessary, but this is at about the point where that's the clearest method:
# Not quite sure where the data is coming from, so I'll assume it's one big chunk
foreach line [split $all_output "\n"] {
if {[regexp {^([^:]*[^:\s])\s*:\s*(.*)$} $line -> key value]} {
if {$value ne "N/A"} {
puts "key is '$key' and value is '$value'"
}
}
}
The critical thing here is the regular expression: ^([^:]*[^:\s])\s*:\s*(.*)$
It's got several bits:
^
— Anchor at the start of the line.([^:]*[^:\s])
— Match (and remember) a sequence of non-colon characters where the last one is also a non-space. (This will be the key
variable's contents.)\s*:\s*
— Match the separator; an arbitrary number (including none) of spaces, followed by a colon, followed by an arbitrary number of spaces.(.*)$
— Match (and remember) all characters from there to the end of the line. (This will be the value
variable's contents.)We do the check against N/A
separately because checking that in the RE, while possible, is fairly miserable. And the split $all_output "\n"
is a standard (and efficient) Tcl idiom for take a big multiline string and convert it into a list of smaller strings, one per line.
Upvotes: 0