TCL-读取文件,额外一行

TCL-读取文件,额外一行,tcl,Tcl,我写了下面的脚本,出于某种原因,它额外输出了第三行(top out.txt&name)。如何阻止它将最后2行输出到输出文件 我想是因为这一行,但不太确定:set line[split[read$list]“\n”] 问题的核心是split使用字段分隔符,而不是字段终止符这就是您看到两者之间差异的地方 如果我们查看文件的字符,我们将看到: abc\nbcd\n。(从技术上讲,\n可以改为\r\n或\r;默认情况下,Tcl会自动适应文本文件。) 如果我们在\n处拆分这些字符,我们将得到以下子字符串:

我写了下面的脚本,出于某种原因,它额外输出了第三行(top out.txt&name)。如何阻止它将最后2行输出到输出文件

我想是因为这一行,但不太确定:set line[split[read$list]“\n”]


问题的核心是
split
使用字段分隔符,而不是字段终止符
这就是您看到两者之间差异的地方

如果我们查看文件的字符,我们将看到:
a
b
c
\n
b
c
d
\n
。(从技术上讲,
\n
可以改为
\r
\n
\r
;默认情况下,Tcl会自动适应文本文件。) 如果我们在
\n
处拆分
这些字符,我们将得到以下子字符串:
abc
bcd
,以及最后一个
\n
之后的字符的空字符串。这意味着,当我们在所有元素之间用
\n
(作为连接字符串)连接
字符串时,我们会再次获得原始字符串


你有几个选择来处理这个问题。我最喜欢的是添加代码来忽略空行;此版本对于各种人工编写的列表特别有用(因为添加注释跳过也相当容易):

另一个选项是使用
-nonewline
选项
读取
,以放弃最后的
\n

    set lines [split [read -nonewline $list] "\n"]
    foreach line $lines {
        puts $outfile "top $dir"
        puts $outfile "name $line"
    }
您也可以在拆分之前
string trimmright
,但这会从末尾剥离多个换行符(如果它们存在的话)


最后,如果你使用一个机器生成的列表,你可以考虑只需得到代码就不会在末尾加一个换行符。有时这是最简单的选择。

尝试
读取-非WLINE$列表
--检查或循环使用
获取
,而不是一次性读取整个文件。另外,如何从
glob abc.txt
获取
out.txt
?你为什么还要用glob呢?由于没有任何通配符,它最多只返回一个具有该模式的文件。。。如果外部
foreach
确实运行了不止一次,那么您第一次只能读取
a.list
,因为它在随后的时间都会位于文件的末尾。。。。
Output
*******
top out.txt 
name abc 
top out.txt 
name bcd 
top out.txt 
name 

set outfile      [open "out.txt" w]
set list         [open "a.list" r]
set dir         "[glob a.txt]"

    foreach ddd $dir {
        set lines [split [read $list] "\n"]
        foreach line $lines {
                puts $outfile "top $dir"
                puts $outfile "name $line"
        }
    }
close $list
close $outfile
    set lines [split [read $list] "\n"]
    foreach line $lines {
        if {$line eq ""} continue
        puts $outfile "top $dir"
        puts $outfile "name $line"
    }
    set lines [split [read -nonewline $list] "\n"]
    foreach line $lines {
        puts $outfile "top $dir"
        puts $outfile "name $line"
    }
    set lines [split [string trimright [read $list] "\n"] "\n"]
    foreach line $lines {
        puts $outfile "top $dir"
        puts $outfile "name $line"
    }