我想使用Tcl脚本将文件的一列转换为列表。我有一个文件名“ input.dat”,其数据分为两列,如下所示:
7 0
9 9
0 2
2 1
3 4
我想将第一列转换为列表,然后按如下方式编写Tcl脚本:
set input [open "input.dat" r]
set data [read $input]
set values [list]
foreach line [split $data \n] {
lappend values [lindex [split $line " "] 0]
}
puts "$values"
close $input
结果显示为:7 9 0 2 3 {} {}
现在,我的问题是这两个额外的“ {}”是什么,脚本中的错误是什么,因为它会产生两个额外的“ {}”,我该如何解决这个问题?
有人可以帮助我吗?
答案 0 :(得分:0)
那些大括号表示空字符串。您最常使用的文件的末尾可能会有几个空行。
您可以通过在lappend
将第一列添加到values
列表之前检查一行来避免这种情况:
foreach line [split $data \n] {
# if the line is not equal to blank, then lappend it
if {$line ne ""} {
lappend values [lindex [split $line " "] 0]
}
}
您也可以在获取结果列表后删除那些空字符串,但这意味着您将有两个循环。如果您无法帮助,它仍然会很有用。
例如,使用lsearch
获取所有非空白的值(在这种情况下可能是最简单的):
set values [lsearch -all -inline -not $values ""]
也可以使用lmap
来达到相同的效果(IMO稍微复杂一些,但是在遇到更复杂的情况时可以提供更大的灵活性):
set values [lmap n $values {if {$n != ""} {set n}}]
答案 1 :(得分:0)
第一个{}由3 4之后的空白行引起。
第二个{}由表示文件结尾的空白行引起。
如果从文件中删除了最后一个空白行,那么将只有一个{}。
如果然后按以下方式对循环进行编码,则将没有{}。
foreach line [split $data \n] {
if { $line eq "" } { break }
lappend values [lindex [split $line " "] 0]
}
@jerry有更好的解决方案
答案 2 :(得分:0)
除非间歇性的空字符串具有某些对程序任务很重要的含义,否则您还可以使用从Tcl列表(带有空字符串元素)到修剪空字符串元素(在结尾处以及之间):
concat {*}[split $data "\n"]