user2045143
user2045143

Reputation: 249

How to break a single TCL list into multiple sublists and easily searchable?

I have single TCL list that is extracted from a text file.

{ First Name = John
Last Name = Doe
Country = USA
Hello;
World;
Hello;
World;
First Name = Dwayne
Last Name = Jhonson 
Country = USA
DoYou;
Smellwhatthe;
RockisCooking;
First Name = Harry 
Last Name = Potter
Country = UK 
The;
BoyWHo;
Lived; }

I want to be able to have the user input the text file(list), First name,last name and country. The code needs to dump out the remaining information for further post processing.

The way I am thinking of coding it right now is with multiple FOR loops, but I am sure there is a more efficient way to do this. Any tips?

proc display_name_information {text_file first_name last_name country} {

set fid [open $text_file r]
set filecontent [read $fid]
set input_list [split $filecontent "\n"]

foreach elem $input_list{
set first_word [lindex $line 0]
set second_word [lindex $line 1]
set third_Word [lindex $line 2]

if {[expr {$first_word== "First"}]  && [expr {$third_word== "$first_name"}]}
*Then similarly check last name and country* 
*and then output everything until I reach the keyword "First Name" again* 

This feels very inefficient for large files.

Upvotes: 0

Views: 55

Answers (1)

sharvian
sharvian

Reputation: 654

A generic method of processing a text file is using a state machine. In the following example, each time a text line matches the expected pattern, the state machine goes to the next state. In each state, you may do further processing, such as extracting data from the text line. Until all lines are done.

set state 0
set chn1 [open input_file r]
array set record [list]
while { [gets $chn1 s1] >= 0 } {
  set s1 [string trim $s1]
  switch -- $state {
    0 - 3 {
      if { [regexp {^First Name\s*=\s*(.*)$} $s1 match data] } {
        set first_name $data
        set state 1
      } elseif { $state == 3 } {
        append record($key) $s1 { }
      }
    }
    1 {
      if { [regexp {^Last Name\s*=\s*(.*)$} $s1 match data] } {
        set last_name $data
        set state 2
      }
    }
    2 {
      if { [regexp {^Country\s*=\s*(.*)$} $s1 match data] } {
        set country $data
        set key ${first_name},${last_name},${country}
        set state 3
      }
    }
  }
}
append record($key) $s1 { }
close $chn1
parray record
exit

Upvotes: 0

Related Questions