我有一个名为time.dat和acc.dat的文件,它们都包含一个包含数值的列。 我想从这些文件中创建包含文件中值的列表。谁知道怎么做?
proc ReadRecord {inFilename outFilenameT outFilenameS} {
if [catch {open $inFilename r} inFileID] {
puts stderr "Cannot open $inFilename for reading"
} else {
set outFileIDS [open $outFilenameS w]
set outFileIDT [open $outFilenameT w]
foreach line [split [read $inFileID] \n] {
if {[llength $line] == 0} {
continue
} else {
puts $outFileIDT [lindex $line 0]
puts $outFileIDS [lindex $line 1]
}
}
close $outFileIDT
close $outFileIDS
close $inFileID
}
};
答案 0 :(得分:6)
这样的事情应该做到这一点:
proc listFromFile {filename} {
set f [open $filename r]
set data [split [string trim [read $f]]]
close $f
return $data
}
set times [listFromFile time.dat]
set accs [listFromFile acc.dat]
[split]
命令在这里为你做了“繁重的工作”。
修改强>
如果您有一个包含两列的单个文件,并且您想要从函数返回该数据集,那么您有两个选择。两者都涉及返回“列表列表”,然后问题是您是否需要两个 N 元素列表,或者 N 两个元素列表。例如,要获取 N 两个元素的列表:
proc readData {filename} {
set result {}
set f [open $filename r]
foreach line [split [read $f] \n] {
lappend result $line
}
return $result
}
或者,要获得两个 N 元素列表:
proc readData {filename} {
set times {}
set accs {}
set f [open $filename r]
foreach line [split [read $f] \n] {
lappend times [lindex $line 0]
lappend accs [lindex $line 1]
}
return [list $times $accs]
}
从技术上讲,您甚至可以将数据作为 2N 元素的列表返回:
proc readData {filename} {
set result {}
set f [open $filename r]
foreach line [split [read $f] \n] {
lappend result [lindex $line 0] [lindex $line 1]
}
return $result
}
这完全取决于您计划如何使用数据。
答案 1 :(得分:1)
如果文件不大并且您不介意将文件句柄保持打开状态直到脚本退出(当它自动关闭时),您可以使用
proc listFromFile {file} { return [split [read [open $file r]] "\n"] }
虽然在\ n上分割意味着如果最后一行有\ n(大多数情况下),你最终会在列表中添加一个额外的空元素。您可以使用
删除它proc listFromFile {file} { return [lreplace [split [read [open $file r]] "\n"] end end] }
最后,如果您希望列表文件有评论,即忽略以#开头的文件,则可以使用
proc listFromFile {file} { return [lsearch -regexp -inline -all [lreplace [split [read [open $file r]] "\n"] end end] {^[^#]}] }
答案 2 :(得分:0)
使用fileutil这变得微不足道:
package require fileutil
fileutil::write testfile.dat {a b c}
set myList [fileutil::cat testfile.dat]
lindex $a 1
这实际上首先将列表写入文件,然后重新读取此数据。由于tcl将列表表示为字符串,我们只需将文件内容分配给变量。
如果您的列表使用换行符作为元素分隔符,或者除了普通空格(制表符,空格)之外的其他内容,则必须使用split
,即split [fileutil::cat testfile.dat] \n
,如上文所述。
注意:内部列表除了字符串表示外,还可以使用列表表示。将sting和list函数调用到列表上会交替地触发表示之间的转换并使其他表示无效。因此,在它之间切换是不好的,但这是一个不同的主题,对于那些感兴趣的人来看tcl wiki on shimmering。