索引文本文件数据

时间:2018-06-10 05:51:41

标签: indexing tcl

我目前有一个包含300行和3列的文本文件。

我需要遍历所有行,使用3列中的值分配3个变量。

这是我的伪代码:

for i=1:300
variable1 = element in ith row, 1st column (i,1)
variable2 = element in ith row, 2st column (i,2)
variable3 = element in ith row, 1st column (i,3)
end

如何调用文本文件中的(i,1),(i,2),(i,3)元素?

谢谢。

1 个答案:

答案 0 :(得分:1)

这个大小的文本文件很简单:它们很容易适合内存。您可能遇到的主要问题是Tcl(与许多编程语言一样)将索引编入从零开始的事物,而不是一个。

# Read the text in
set f [open "thefile.txt"]
set data [read $f]
close $f

# Split the data into a list of lines
set data [split $data "\n"]

# Now go over the lines and extract the fields
for {set i 0} {$i < 300} {incr i} {
    set line [lindex $data $i]
    set fields [split $line]; # NB: ASSUMES FIELDS SEPARATED BY SINGLE SPACES
    set variable1 [lindex $fields 0]
    set variable2 [lindex $fields 1]
    set variable3 [lindex $fields 2]
}

但是有更好的方法可以做到这一点。特别是,由于我们按顺序执行所有行并始终提取连续范围的字段,因此我们可以更简洁:

set f [open "thefile.txt"]
set data [read $f]
close $f

foreach line [split $data "\n"] {
    lassign [split $line] variable1 variable2 variable3
}

最后的复杂性是字段不一定用单个空格分割;当有(甚至有时候)字段之间存在多个空格时,它会失败,因为split实际上是一个非常愚蠢的命令。我们通过编写一些代码来解决这个问题,使用一个更强大的Tcl命令为我们进行拆分;在这种情况下,regexp(正则表达式匹配命令)是正确的工具:

set f [open "thefile.txt"]
set data [read $f]
close $f

foreach line [split $data "\n"] {
    lassign [regexp -all -inline {\S+} $line] variable1 variable2 variable3
}

这种方式有点长,但对现实世界的数据更强大。 (Tcllib textutil包有其他方法可以进行这种拆分,但正确的方法实际上取决于你的输入数据是什么。你比我们更了解这一点!)

另外,不要忘记实际使用您分配给的变量。只是分配它们是一个非常空洞的练习。