Tcl中的数组从* csv输入文件中分配

时间:2015-04-20 09:38:00

标签: arrays tcl

我有一个* csv文件,其中数据如下。

$ cat file1.csv

"power_domains"    "VDD1#1#T"  "VDD1#1#B"  "VDD1#2#L"  "VDD1#2#R" 
 block1               6           6           6            6
 block2               0           3           2            4
 block3/a             2           2           1            1

在上面的文件中。我想按如下方式分配数据

block1(VDD1#1#T) = 6 , block1(VDD1#1#B) = 6 , block1(VDD1#2#L) = 6 , block1(VDD1#2#R)=6

block2(VDD1#1#T) = 0 ,  block2(VDD1#1#B) = 3 , block2(VDD1#2#L) = 2 , block2(VDD1#2#R)=4


block3/a(VDD1#1#T) = 2 ,  block3/a(VDD1#1#B) = 2 , block3/a(VDD1#2#L) = 1 , block3/a (VDD1#2#R)=1

要分配上述数据,我尝试了以下代码:

if { [file exists .tmp.PG_Ring] == 1} {
    set fp_ring [open .tmp.PG_Ring r]
    set fp_ring_data [read $fp_ring]
    set fp_ring_row_data [split $fp_ring_data "\n"]
    foreach PG_Ring_row1 $fp_ring_row_data {
    set PG_Ring_row [regexp -inline -all {\S+} PG_Ring_row1]
    set PG_Ring_row [string map  { "\"" "" "\{" "" "\}" "" } $PG_Ring_row1]
    set  pg_ring_column [lindex $PG_Ring_row 0]
    set Rings_distance 5
    set pg_ring_flag [string index $PG_Ring_row 0]
    if { $pg_ring_flag != "#" && $pg_ring_flag != "" } {
            if { [ string match -nocase  "Rings_distance" $pg_ring_column ] }  {
            set Rings_distance [lindex $pg_ring_column 1]
            } elseif { [ string match -nocase "power_domains" $pg_ring_column ] }  {
            set no_ring_domains [llength  $PG_Ring_row ]
            #array set ring_domains [lrange $PG_Ring_row 1 end]
            set i 1
            while  {$i < $no_ring_domains} {
            set power_domain($i) [lindex $PG_Ring_row $i]
            puts "$i $power_domain($i)"                             
            incr i
            }
            }
    set j 1
    puts test
    puts $no_ring_domains
    puts $pg_ring_column
    while { $j < $no_ring_domains } {
    **set ($pg_ring_column)($power_domain($j))  [lindex $PG_Ring_row $j**]
    incr j
    puts "$($pg_ring_column)($power_domain($j))  "
    }

在上面的代码数组中,我无法指定:

 *set ($pg_ring_column)($power_domain($j))  [lindex $PG_Ring_row $j**

此声明无效。你能帮我在TCL中分配数组吗?

2 个答案:

答案 0 :(得分:2)

动态数组名称会给你带来很多痛苦。更好的方法是使用dict或使用数组并伪造多维方面:

array set data {}
set fid [open "file1.csv" r]
set header [regexp -all -inline {\S+} [regsub -all {"} [gets $fid] ""]]
while {[gets $fid line] != -1} {
    set fields [regexp -all -inline {\S+} $line]
    set block [lindex $fields 0]
    for {set i 1} {$i < [llength $fields]} {incr i} {
        set data($block,[lindex $header $i]) [lindex $fields $i]
    }
}
close $fid
parray data

输出

data(block1,VDD1#1#B)   = 6
data(block1,VDD1#1#T)   = 6
data(block1,VDD1#2#L)   = 6
data(block1,VDD1#2#R)   = 6
data(block2,VDD1#1#B)   = 3
data(block2,VDD1#1#T)   = 0
data(block2,VDD1#2#L)   = 2
data(block2,VDD1#2#R)   = 4
data(block3/a,VDD1#1#B) = 2
data(block3/a,VDD1#1#T) = 2
data(block3/a,VDD1#2#L) = 1
data(block3/a,VDD1#2#R) = 1

答案 1 :(得分:0)

处理CSV数据时,建议您使用Tcllib中的csv包。这是一个将数据读入struct::matrix(另一个Tcllib包)的命令。

package require struct::matrix
package require csv

# Read it in
set m [struct::matrix]
set f [open "file1.csv"]
csv::read2matrix $f $m
close $f

# Now use the matrix ops to work with it.
set titles [$m get row 0]
set domains [$m get column 0]
# ...

# Write it out
set f [open "file2.csv" w]
csv::writematrix $m $f
close $f