[英]TCL - read a file, extra line
I have written the script below, and for some reason it output an extra 3rd line (top out.txt & name ).我写了下面的脚本,出于某种原因它 output 额外的第 3 行(top out.txt & name)。 How do I stop it from outputing the last 2 line to the output file.
如何阻止它输出最后 2 行到 output 文件。
I think is because of this line but not too sure: set lines [split [read $list] "\n"]我认为是因为这一行但不太确定:set lines [split [read $list] "\n"]
Input put file - a.txt
**********************
abc
bcd
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
The core of the issue is that split
works with field separators and not field terminators;问题的核心是
split
使用字段分隔符而不是字段终止符; this is where you see the difference between the two.这就是您看到两者之间区别的地方。
If we look at the characters of your file, we'll see this: a
b
c
\n
b
c
d
\n
.如果我们查看文件的字符,我们会看到:
a
b
c
\n
b
c
d
\n
。 (Technically, the \n
might instead be \r
\n
or \r
; Tcl auto-adapts to that by default for text files.) If we split
those characters at the \n
, we get these substrings: abc
, bcd
, and the empty string for the characters after that final \n
. (从技术上讲,
\n
可能改为\r
\n
或\r
;对于文本文件,默认情况下 Tcl 会自动适应它。)如果我们在\n
处split
这些字符,我们会得到这些子字符串: abc
、 bcd
和最后一个\n
之后的字符的空字符串。 This means that when we join
the strings with \n
(as the joiner string) between all the elements, we get the original string back again.这意味着当我们在所有元素之间使用
\n
(作为join
字符串)连接字符串时,我们会再次得到原始字符串。
You've got a few options for dealing with this.你有几个选择来处理这个问题。 My favourite is to add code to ignore blank lines;
我最喜欢的是添加代码来忽略空行; versions of this are particularly useful for all sorts of human-written lists (as it's fairly easy to also add in comment skipping):
这个版本对于各种人工编写的列表特别有用(因为添加注释跳过也相当容易):
set lines [split [read $list] "\n"]
foreach line $lines {
if {$line eq ""} continue
puts $outfile "top $dir"
puts $outfile "name $line"
}
Another option is to use the -nonewline
option to read
to discard that final \n
:另一种选择是使用
-nonewline
选项read
以丢弃最后的\n
:
set lines [split [read -nonewline $list] "\n"]
foreach line $lines {
puts $outfile "top $dir"
puts $outfile "name $line"
}
You could also string trimright
before splitting, but that would strip multiple newlines from the end (if they're present).您也可以在拆分之前将
string trimright
,但这会从末尾去除多个换行符(如果它们存在)。
set lines [split [string trimright [read $list] "\n"] "\n"]
foreach line $lines {
puts $outfile "top $dir"
puts $outfile "name $line"
}
Finally, if you're using a machine-generated list, you could consider just getting that code to not put a newline at the end.最后,如果您使用的是机器生成的列表,您可以考虑只让该代码不在末尾放置换行符。 Sometimes that's the easiest option of all.
有时这是最简单的选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.