Reputation: 19
I have this string:
1, RotD50, 88, 0.1582, 1.2264, -, 7.4, 23.6, 0.2, "San Fernando", 1971, "Santa Felita Dam (Outlet)", 6.61, Reverse, 24.69, 24.87, 389.0, 0.125, 1.2939, RSN88_SFERN_FSD172.AT2, RSN88_SFERN_FSD262.AT2 , RSN88_SFERN_FSD-UP.AT2
I want to find the indices of RSN88_SFERN_FSD172.AT2
and RSN88_SFERN_FSD262.AT2
I have tried a few scripts (like the following) but want to see if someone can help me with a rigorous script?
set currentdirc [pwd]
set fp [open _SearchResults.csv]
set count 1
foreach line [split [read $fp] \n] {
foreach word [split $line] {
set word [string trim $word ","]
set index [lsearch -exact $word "Horizontal-1 Acc.Filename"]
puts "$index"
}
}
Upvotes: 1
Views: 4218
Reputation: 13252
You are going to need this:
package require csv
As before, break the data into lines and iterate over those lines. Trim the data first to avoid empty lines before or after.
foreach line [split [string trim [read $fp]] \n] {
Instead of trying to split the csv data using the split
command, use the dedicated command ::csv::split
from the csv
package in Tcllib. You probably have it in your Tcl installation already.
set words [::csv::split $line]
When your line is split, there is unwanted whitespace around many data fields. Let's trim it off.
set words [lmap word $words {string trim $word}]
Finally, you can search for data in the list of words. Searching in each word as you did is pointless.
set index [lsearch $words RSN88_SFERN_FSD262.AT2]
Putting it together:
foreach line [split [string trim [read $fp]] \n] {
set words [::csv::split $line]
set words [lmap word $words {string trim $word}]
set index [lsearch $words RSN88_SFERN_FSD262.AT2]
puts $index
}
Documentation: csv (package), foreach, lmap (for Tcl 8.5), lmap, lsearch, package, puts, read, set, split, string
Upvotes: 2
Reputation: 71538
I would use the csv package to do that task, since you are dealing with a csv file. Splitting blindly will split 1, RotD50, 88, 0.1582, 1.2264, -, 7.4, 23.6, 0.2, "San Fernando"
things into, for example (each element on their own line):
1,
RotD50,
88,
0.1582,
1.2264,
-,
7.4,
23.6,
0.2,
"San
Fernando"
So my suggestion is:
set currentdirc [pwd]
set fp [open [file join $currentdirc _SearchResults.csv] r]
package require csv
foreach line [split [read $fp] \n] {
set words [::csv::split $line]
set index [lsearch -exact $words "Horizontal-1 Acc.Filename"]
puts $index
}
Also the list of words is the whole line. So if you want to loop through the words, you would do if {$word eq "Horizontal-1 Acc.Filename"}
instead and you would have to use count
(that I removed in my suggestion) to keep track of the index.
If for some reason you cannot use the csv package, you can try using this instead of the line containing ::csv::split
:
set all [regexp -all -inline -- {\"[^\"]+\"|[^,]+} $line]
set words [lmap w $all {set w [string trim $w {\" }]}]
(I'm using \"
for the quotes only for the sake of proper syntax highlighting, you can safely use "
alone)
Upvotes: 1