2012-08-14 68 views
1

我有一個半結構化的文本文件,我想從中提取值並保存起來以備後用。 該文件有一些模擬環境的配置數據env。由不同的子系統組成,對於其中一個子系統,我希望找到它們的數量,以及它們的具體類型。 這是文件是如何構成的使用Tcl解析結構化文件並選擇一些值?

<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> 

現在我想知道,多久模式PLC_BERGHOF在文件中進行,其實我能做到這一點了,但現在如果發現我想保存在某種聯想。對之前的行的鍵值對和陣列發現的行之後的3行進行排列。

後來在我的劇本,我想能夠訪問這樣的價值觀: 集plc1_IP_Address陣列[「plc1_IP_Address」], 訪問,這並不真正重要的確切sysntax,代碼剛剛進入Tcl腳本

感謝您的幫助

回答

3

如果您正在使用的Tcl 8.5那麼我建議你逐行讀取文件中的行建立了一套dict對象來保存每個子系統名稱的集合:項目對。然後,您可以創建一個這樣的詞典列表來表示整個文件或任何對您有意義的內容。然後是這樣的:

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]" 
    } 
} 

雖然從你的描述的聲音:grep -A 3 PLC_BERGHOF就足夠了。

如果不使用8.5,那麼您沒有dict,但名稱項目對的列表可以用幾乎相同的方式進行管理。您最後只能使用lsearch或將對的列表轉換爲數組,以便查找。

0
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 

然後你可以使用

if {$data(Subsystem_Type eq "PLC_BERGHOF"} { 
    puts "IP address is: $data(IP_Address)" 
} 

我假設你的文件實際上是格式化爲以下內容,你遇到麻煩你的問題格式化恰到好處:

<Begin_Subsystem_Configuration> 
Subsystem_Name:"PLC1_ARR": 
... 
<End_Subsystem_Configuration> 
+0

如果我們有什麼,多個IP地址線。如何grep所有IP地址。 Subsystem_Type:PLC_BERGHOF: IP_Address:「11.70.9.13」: Port_Numbers:3500:3500: Alive_Message_Period:10:如何grep「11.70.9.13」和10.70.9.11。 – rcubefather 2014-09-03 11:26:42

+0

然後,如果我們替換它,它會打印任何內容,而不是'設置數據([lindex $ fields 0])$ values''您希望'lappend data([lindex $ fields 0])$ values' – 2014-09-03 12:28:04

+0

。如何解決這個問題。請幫忙。 – rcubefather 2014-09-04 15:19:48