我有一个CSV文件,其中包含许多行和列2,其中类似于:
Horizontal-1 Acc. Filename Horizontal-2 Acc. Filename RSN88_SFERN_FSD172.AT2 RSN88_SFERN_FSD262.AT2 RSN164_IMPVALL.H_H-CPE147.AT2 RSN164_IMPVALL.H_H-CPE237.AT2 RSN755_LOMAP_CYC195.AT2 RSN755_LOMAP_CYC285.AT2 RSN1083_NORTHR_GLE170.AT2 RSN1083_NORTHR_GLE260.AT2 RSN1614_DUZCE_1061-N.AT2 RSN1614_DUZCE_1061-E.AT2 RSN1633_MANJIL_ABBAR--L.AT2 RSN1633_MANJIL_ABBAR--T.AT2 RSN3750_CAPEMEND_LFS270.AT2 RSN3750_CAPEMEND_LFS360.AT2 RSN3757_LANDERS_NPF090.AT2 RSN3757_LANDERS_NPF180.AT2 RSN3759_LANDERS_WWT180.AT2 RSN3759_LANDERS_WWT270.AT2 RSN4013_SANSIMEO_36258021.AT2 RSN4013_SANSIMEO_36258111.AT2 RSN4841_CHUETSU_65004NS.AT2 RSN4841_CHUETSU_65004EW.AT2 RSN4843_CHUETSU_65006NS.AT2 RSN4843_CHUETSU_65006EW.AT2 RSN4844_CHUETSU_65007NS.AT2 RSN4844_CHUETSU_65007EW.AT2 RSN4848_CHUETSU_65011NS.AT2 RSN4848_CHUETSU_65011EW.AT2
在CSV文件中,我想查找标题“Horizontal-1 Acc.Filename和Horizontal-2 Acc.Filename”,然后逐行获取这些标题下每行的名称一次?
有什么建议吗?
由于 RG。
答案 0 :(得分:1)
package require csv
package require struct::matrix
::struct::matrix m
m add columns 2
set chan [open data.csv]
::csv::read2matrix $chan m
close $chan
lassign [m get row 0] header1 header2
for {set r 1} {$r < [m rows]} {incr r} {
puts -nonewline [format {%s = %-30s } $header1 [m get cell 0 $r]]
puts [format {%s = %s} $header2 [m get cell 1 $r]]
}
m destroy
我发现处理csv数据集的最简单方法是使用matrix
。 matrix
是一种二维向量,带有用于搜索,排序和重新排列列和行的内置函数。
首先,创建一个矩阵并将其命名为m
。它从头开始有两列,但还没有行。
::struct::matrix m
m add columns 2
打开一个频道来读取数据文件。将通道和矩阵名称传递给::csv::read2matrix
命令。此命令将读取csv数据并为每个数据行创建矩阵行。数据字段存储在列中。
set chan [open data.csv]
::csv::read2matrix $chan m
close $chan
要获取标题字符串,请检索第0行。
lassign [m get row 0] header1 header2
要迭代数据行,请从1(如果我们没有标题,0)到m rows
下面,这是矩阵中的行数。
有一个方便的report
工具适用于矩阵,但我在这里只使用for
循环。我猜你想要的数据是什么:
for {set r 1} {$r < [m rows]} {incr r} {
puts -nonewline [format {%s = %-30s } $header1 [m get cell 0 $r]]
puts [format {%s = %s} $header2 [m get cell 1 $r]]
}
如果你已完成矩阵,你也可以将其销毁。
m destroy
评论中特定问题的解决方案。
package require csv
package require struct::matrix
::struct::matrix m
set chan [open foo.csv]
::csv::read2matrix $chan m , auto
close $chan
set f1 [m search column 0 "Result ID"]
set headerRow [lindex $f1 0 1]
set f2 [m search rect 0 $headerRow 0 [expr {[m rows] - 1}] ""]
set f3 [m search row $headerRow "Horizontal-1 Acc. Filename"]
set f4 [m search row $headerRow "Horizontal-2 Acc. Filename"]
set top [expr {$headerRow + 1}]
set bottom [expr {[lindex $f2 0 1] - 1}]
set left [lindex $f3 0 0]
set right [lindex $f4 0 0]
puts [format {Vector=[ %s ]} [concat {*}[m get rect $left $top $right $bottom]]]
m destroy
显然,您需要将文件名更改为正确的名称。没有错误处理:在这样一个简单的脚本中,最好让脚本失败并纠正错误。
解决第二个问题,评论如下:
package require csv
package require struct::matrix
::struct::matrix m
set chan [open _SearchResults.csv]
::csv::read2matrix $chan m , auto
close $chan
set f1 [m search column 0 {Result ID}]
set headerRow [lindex $f1 0 1]
set f2 [m search -glob rect 0 $headerRow 0 [expr {[m rows] - 1}] { These*}]
set numofRow [lindex $f2 0 1]
set headercol1 [m search row $headerRow { Horizontal-1 Acc. Filename}]
set headercol2 [m search row $headerRow { Horizontal-2 Acc. Filename}]
set indexheaderH1col [lindex $headercol1 0 0]
set indexheaderH2col [lindex $headercol2 0 0]
set rows [m get rect $indexheaderH1col [expr {$headerRow+1}] $indexheaderH2col [expr {$numofRow-1}]]
set rows [lmap row $rows {
lassign $row a b
list [string trim $a] [string trim $b]
}]
foreach row $rows {
puts [format {%-30s %s} {*}$row]
}
puts [format {Vector=[ %s ]} [concat {*}$rows]]
评论:
read2matrix
使用auto
lmap
命令的部分修复了文档: + (operator), - (operator), < (operator), chan, close, concat, csv (package), expr, for, format, incr, lassign, lindex, lmap (for Tcl 8.5), lmap, open, package, puts, set, struct::matrix (package), {*} (syntax)
答案 1 :(得分:0)
擦除所有
package require csv
package require struct::matrix
::struct::matrix m
m add columns 2
set chan [open _SearchResults.csv]
::csv::read2matrix $chan m , auto
close $chan
set f1 [m search column 0 {Result ID}]
set headerRow [lindex $f1 0 1]
set f2 [m search rect 0 $headerRow 0 [expr {[m rows] - 1}] {}]
set numofRow [lindex [lindex $f2 0 1]]
set headercol1 [m search row $headerRow { Horizontal-1 Acc. Filename}]
set headercol2 [m search row $headerRow { Horizontal-2 Acc. Filename}]
set indexheaderH1col [lindex $headercol1 0 0]
set indexheaderH2col [lindex $headercol2 0 0]
set header1 [m get cell $indexheaderH1col $headerRow]
set header2 [m get cell $indexheaderH2col $headerRow]
for {set r [expr $headerRow+1]} {$r < [expr $numofRow-1]} {incr r} {
puts [format {%-30s %s} [m get cell $indexheaderH1col $r] [m get cell $indexheaderH2col $r]]
}
set vector [concat {*}[m get rect $indexheaderH1col [expr $headerRow+1] $indexheaderH2col [expr $numofRow-1]]]
puts [format {Vector=[ %s ]} [concat {*}[m get rect $indexheaderH1col [expr $headerRow+1] $indexheaderH2col [expr $numofRow-1]]]]