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
Ich finde, dass der einfachste Weg, mit csv Datensatz zu behandeln ist durch ein matrix
verwenden. A matrix
ist eine Art zweidimensionaler Vektor mit Einbauten zum Suchen, Sortieren und Neuanordnen von Spalten und Zeilen.
Erstellen Sie zuerst eine Matrix und nennen Sie sie m
. Es wird zwei Spalten von Anfang an haben, aber noch keine Zeilen.
::struct::matrix m
m add columns 2
Öffnen Sie einen Kanal, um die Datendatei zu lesen. Übergeben Sie den Kanal und den Matrixnamen an den Befehl ::csv::read2matrix
. Dieser Befehl liest die CSV-Daten und erstellt eine Matrixzeile für jede Datenzeile. Die Datenfelder sind in den Spalten gespeichert.
set chan [open data.csv]
::csv::read2matrix $chan m
close $chan
die Header-Strings erhalten, abrufen Zeile 0.
lassign [m get row 0] header1 header2
über die Datenzeilen zu durchlaufen, von 1 gehen (wenn wir nicht Header haben, 0) auf knapp m rows
, Das ist die Anzahl der Zeilen in der Matrix.
Es gibt eine handliche report
Einrichtung, die gut mit Matrizen funktioniert, aber ich werde nur eine for
Schleife hier verwenden. Ich schätze, wie Sie die Daten darstellen möchten:
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]]
}
Wenn Sie mit der Matrix fertig sind, können Sie es auch zerstören.
m destroy
Lösung für das spezifische Problem in den Kommentaren.
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
Offensichtlich müssen Sie den Dateinamen auf den richtigen Namen ändern. Es gibt keine Fehlerbehandlung: In einem so einfachen Skript ist es besser, nur das Skript fehlschlagen zu lassen und alles zu korrigieren, was schief gelaufen ist.
Lösung für das zweite Problem, Kommentare unter:
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]]
Kommentare:
- Sie brauchen nicht die Anzahl der Spalten zu setzen, wenn Sie
read2matrix
mit auto
verwenden
- In dieser Datei befindet sich nach der Tabelle keine leere Zelle.Stattdessen müssen wir nach einer Zeichenfolge suchen, die mit "These" beginnt.
- Da jede Zelle ein Leerzeichen gefolgt von dem Wert enthält, müssen wir den Abstand um den Wert verringern, da andernfalls die Verkettung fehlschlägt. Der Teil mit dem
lmap
Befehl behebt, dass
- Always brace your expressions
Dokumentation: + (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)
Möchten Sie dies in TCL schreiben - haben Sie es deshalb mit TCL getaggt? Was hast du bisher versucht? Sobald Sie diese Zeilen haben, was wollen Sie mit ihnen machen? anzeigen sie? einen Kalk machen? –
Hallo Nick Ja, es wird in tcl sein. – Reza