输入:
@@@@@@@@@@@@@@
my_data1 12 23 34
my_data2 10 23 4
my_data3 1 2 34
my_data4 12 3 3
依旧......
输出:
my_data1 12 23 34
我希望我的Tcl代码能够查找第1行表达式,即从@
(^@
)开始,并在下一行打印 。
答案 0 :(得分:0)
以下是通过逐行读取文件来执行所需操作的代码。
set fp [open "somefile" r]
set file_data [read $fp]
close $fp
set read_next 0
# Process data
foreach line [split $file_data "\n"] {
if {[string index $line 0] == "-"} {
set read_next 1
continue
}
if {$read_next == 1} {
puts $line
}
set read_next 0
}
答案 1 :(得分:0)
最简单的方法是读取所有数据并使用合适的lsearch
。
set f [open $filename]
set lines [split [read $f] "\n"]
close $f
set matched [lsearch -all -regexp $lines {^@}]
foreach idx $matched {
puts [lindex $lines [expr {$idx + 1}]]
}
假设你想要一行以@
开头的所有行。要获得第一个:
set idx [lsearch -regexp $lines {^@}]
if {$idx >= 0} {
puts [lindex $lines [expr {$idx + 1}]]
}
也就是说,没有-all
并且没有对结果进行循环,而是检查我们没有得到-1
(记录的不匹配指示符)。
答案 2 :(得分:0)
其他解决方案很好,但可能有点过于复杂。提供一些对比:
while {![eof $in]} { if {[regexp {^@} [gets $in]]} { puts [gets $in] ; break } }
这假设in
的值是一个可供阅读的频道(可以是stdin
,也可以是打开的文件)。
它背后的逻辑是:读一条线;如果匹配,再读一行并打印,然后退出。重复直到输入用尽。
ETA:如果单行内容难以直观地解析,这就是更多行上的相同内容:
while {![eof $in]} {
if {[regexp {^@} [gets $in]]} {
puts [gets $in]
break
}
}
这样的写作使结构更加清晰,但这个解决方案基本上是一个单行,真的。