Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Parsing Text File with TCL??

Status
Not open for further replies.

JRyanCon

Technical User
Aug 19, 2004
47
US
I was wondering if it is possible to parse a text file using TCL. For instance if I had the following in a file called file.txt:
-------------
Ryan,3453,
Jack,0,
Tom,8948,
blah,99,
-------------

And I wanted to pull just the numbers out as variables how would I go about that? With Linux I know I could use built in commands and exec and parse it that way like this:
set var [exec grep Ryan file.txt | cut -d, -f2]


But if I dont want to use a 3rd party utility could I parse the same file using just TCL? If so how would the syntax be?

Thanks for your time,


Ryan
 
easy...
Code:
set File [open [file join [pwd] "file.txt"]]
foreach {i} [split [read $File] \n] {
  lappend ListofResult [lindex [split $i ,] 1]
}
close $File

puts $ListofResult

would output something like:
{3453} {0} {8948} {99}

i did not test it tough
but you get the idea...

I was as quick as possible
 
Wow, that was about as fast as possible, Thanks! Your right if I run it its: 3453 0 8948 99

What I would need to do is look at each separately and save the number as a variable. So in the end I would have 4 different Variables. The text file generated always looks the same but the ,number, changes. So I would just want to beable to look through the file and pick out each number separately as apposed to all of them in one variable.

so like if the file was:

Ryan,3453,
Jack,0,
Tom,8948,
blah,99,

and then have
puts "$ryan"
puts "$jack"
puts "$tom"
puts "$blah"

Thanks again for your help

Ryan
 
There are 2 ways to do this that are illustrative of Tcl's power.

Starting from the list you get from following fl0ra's advice: Ryan,3453 Jack,0 Tom,8948 blah,99 - let's call this list, "al".

Then, method 1:
foreach pair $al {set [lindex [split $pair ,] 0] [lindex [split $pair ,] 1]}

Now the variable, Ryan, has the value 3453, etc.

Method 2:
set bl [string map {, " "} $al];# change the commas to spaces
array set a $bl

Now you have an array, a, whose indices are Ryan, Jack, Tom, and blah; and whose values for those indices are 3453, 0, 8948, and 99.



Bob Rashkin
rrashkin@csc.com
 
Thanks for the Reply Bong. I am fairly new to TCL so while I am sure you made perfect sense, I had a hard time getting my head around what you said. Now some of the values in this file I will not want to do anything with. so if I have
the following in a file called file.txt.

Ryan,3453,
Jack,0,
Tom,8948,
blah,99,

Now the file I am parsing has ALOT of text in it in this format, but I will only want a handful of values from it. So I would just want to parse through the file then have an output like:

puts "Ryans Value is $ryan"
puts "Jacks Value is $jack"

So you are saying use both flOra's very helpful code and add yours to it how? Could you do that and show me what the full code would look like? I guess I am just used to using grep and such where you look for a value like "grep ryan file.txt". And this is a lot different.

Thanks for the help and sorry if I am not getting it.
Ryan
 
I think it's still simplest to read and process the whole file, then only use the values you want. Assuming it's acceptable for the variable to be named, say, "Ryan", instead of "ryan", I would do it like this:
Code:
set fid [open <text file name> r]
set flist [split [read $fid] \n];#each line of your file is a list element
close $fid
foreach pair $flist {
   set pair [string map {, " "} $pair] ;#change "," to " "
   set [lindex $pair 0] [lindex $pair 1];# eg set Ryan 3453
}
puts "Ryan's value is "$Ryan


Bob Rashkin
rrashkin@csc.com
 
That worked like a charm. Thanks alot....now I can try and go through this and figure out what its all doing, haha.

RYan
 
hehe
Hope you'll give Tcl/Tk the credit it deserves... because it is a very good and powerfull language once you mastered a few things...

 
TCL seems really open as far as what it can do. Just I am having a bit of trouble understanding how it parses. Like I said I have only used Unix utils to parse, such as grep cut awk, and whatnot. This last one wasn't so bad since the format was very structured. But how do you look for a known variable in a not so structured file. For instance if I have a file called document.txt that looks like:

-----------start document.txt example--
A paragraph up here. Just some text that tells whats in the document and what not. not structured and no data will be pulled from up here.

value value2 value3 value4
===== ====== ====== ======
1300 2000 05 5300
4000 12 09 3000


---------------End document.txt-------------------

So how would I go about pulling individually value value2 and value3 from the row where value4 is 5300? I have the Book Practical Programming in TCL/TK but I cant seem to find what it is I want to do. I pull value4 as a variable else where, so I want to be able to pull value, value2 and value3 where value4 = known variable. Is this possible?

thanks for your help,

Ryan
 
Well, you have to have some structure. In the sample you gave above, you have 4 values separated by spaces. That's actually the easiest since you can treat a string with spaces as a list (saves you a relatively trivial step).
Code:
#read until "value"
set fid [open document.txt r]
set word1 " "
while ($word1!= "value") {
 set line [gets $fid]
 set word1 [lindex $line 0]
}
lappend tbl1 $line
foreach line [split [read $fid] \n] {lappend tbl1 $line}
close $fid
now your "tbl1" is a list whose first element is {value value2 value3 value4}, 2nd element is {===== ===== ===== =====}, 3rd element is {1300 2000 05 5300}, etc.
Let's say you don't know the structure, just that there is one and the first line tells you.
Code:
set keyline [lindex $tbl1 0]
set keyix [lsearch $keyline "value3"]
#keyix is the index in each line of value3
#now what do you want to do?  Say the 3rd set of values?  
#That's the 5th element (index 4)
set newVal3 [lindex [lindex $tbl1 4] $keyix]

Bob Rashkin
rrashkin@csc.com
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top