#csv #scripting #tcl
#csv #сценарии #tcl
Вопрос:
Я пытаюсь проанализировать CSV, чтобы проверить, присутствует ли один из заголовков. Иногда я ожидал бы пятой колонки с arbitraryHead
date time value result arbitraryHead
val1 d1 10 fail
val2 d2 15 norun
Я пытался прочитать первую строку, а затем распечатать ее. Но это не работает…
Как я могу прочитать первую строку и распечатать все заголовки?
set fh [open $csv_file r]
set data [list]
set line [gets $fh line]
lappend data [split $line ,]
close $fh
foreach x $data {
puts "$xn"
}
Ответ №1:
При чтении CSV-файла лучше всего использовать csv-пакет в Tcllib, поскольку он обрабатывает все неудобные крайние случаи в этом формате.
В частности, csv::split
это особенно полезно (наряду с csv::join
созданием CSV-файла). Или различные функции, которые действуют как оболочки вокруг него. Вот как вы могли бы использовать это в вашем случае
package require csv
set fh [open $csv_file r]
# Your data appears to be actually tab-separated, not comma-separated...
set data [csv::split [gets $fh] "t"]
close $fh
foreach x $data {
puts "$xn"
}
Ваша фактическая непосредственная ошибка заключалась в следующем:
set line [gets $fh line]
Форма с двумя аргументами gets
записывает прочитанную строку в переменную, указанную во втором аргументе, и возвращает длину прочитанной строки (или -1 при невозможности прочитать полную строку, что может быть полезно в сложных случаях, которые здесь не важны). Затем вы присваиваете это значение той же переменной с set
, теряя строку, которая была там записана. Вместо этого вам следует использовать один из следующих (за исключением того, что вы должны использовать должным образом протестированный пакет для чтения CSV-файлов):
gets $fh line
set line [gets $fh]
Форма с одним аргументом gets
возвращает прочитанную строку, что может затруднить распознавание ошибок, но является очень удобным.
Ответ №2:
Самое простое, что вы можете сделать, это операция сопоставления строк, просто найдите нужный заголовок, который вы хотели проверить.
Как и было запрошено в следующем коде, я проверяю «arbitraryHead»
set fh [open $csv_file r]
set contents [read $fh ]
foreach x $contents {
if {[string match "*arbitraryHead*" $x]} {
puts "HEAD FOUND"
}
}
close $fh
Надеюсь, это решит вашу проблему