Reputation: 577
I have got a semi structured text file, from which I want to extract values and save them for later use. The file has some config data for a simulation environment, the env. is made up of different sub-systems, for one of these sub-systems I want to find the number of them, and their specific type. This is how the file is structured
<Begin_Subsystem_Configuration>
Subsystem_Name:"PLC1_ARR":
Subsystem_Identifier:0x01B1B000:
Subsystem_Type:PLC_BERGHOF:
IP_Address:"10.70.9.11":
Port_Numbers:3500:3500:
Alive_Message_Period:10:
Max_Communication_Latency:5:
Switch_Over_Timeout:15:
Member_Count:6:
Subsystem_Member_1:77:77: # PS SR1
Subsystem_Member_2:106:106: # SZ PTHA
Subsystem_Member_3:110:110: # SZ PTH1
Subsystem_Member_4:310:310: # SZ YL1
Subsystem_Member_5:311:311: # SZ DOOR1
Subsystem_Member_6:312:312: # SZ FIRE1
<End_Subsystem_Configuration>
Now I want to know, how often the pattern PLC_BERGHOF Occur in the file, I actually can do that already, but now if it is found I would like to save in some sort of assoc. array the key-value pair of the line before, and the 3 lines after the line in which the patter found.
Later on in my script I would like to be able to access the values like that: set plc1_IP_Address array['plc1_IP_Address'], the exact sysntax of accessing that doesnt really matter, the code has just to go into a Tcl Script
Thanks for the help
Upvotes: 1
Views: 1009
Reputation: 246754
set fh [open "file.data" r]
array set data []
while {[gets $fh line] != -1} {
switch -exact -- $line {
"<Begin_Subsystem_Configuration>" -
"<End_Subsystem_Configuration>" {continue}
default {
set fields [split $line ":"]
set values [list]
foreach value [lrange $fields 1 end-1] {
if {[string match {"*"} $value]} {
lappend values [string range $value 1 end-1]
} else {
lappend values $value
}
}
set data([lindex $fields 0]) $values
}
}
}
close $fh
Then you can use
if {$data(Subsystem_Type eq "PLC_BERGHOF"} {
puts "IP address is: $data(IP_Address)"
}
I assume your file is actually formatted as following, and you were having trouble getting your question formatted just right:
<Begin_Subsystem_Configuration>
Subsystem_Name:"PLC1_ARR":
...
<End_Subsystem_Configuration>
Upvotes: 0
Reputation: 33193
If you are using Tcl 8.5 then I suggest you read the file line by line building up a set of dict objects to hold each subsystem as a collection of name:item pairs. You can then create a list of such dicts to represent the whole file or whatever makes sense to you. Then something like:
foreach config $list_of_dicts {
if {[dict get $config Subsystem_Type] eq "PLC_BERGHOF"} {
puts "[dict get $config IP_Address]\n[dict get $config Port_Numbers]"
}
}
Although from the sound of your description: grep -A 3 PLC_BERGHOF
would be sufficient.
If not using 8.5 then you don't have dict
but a list of name item pairs can be managed in much the same way. You just end up using lsearch
more or converting the list of pairs into an array just to look things up.
Upvotes: 3