我有一个* 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中分配数组吗?
答案 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