在提到的行后面划一条线

时间:2014-02-13 09:31:27

标签: regex tcl

输入:

@@@@@@@@@@@@@@
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行表达式,即从@^@)开始,并在下一行打印

3 个答案:

答案 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
    }
}

这样的写作使结构更加清晰,但这个解决方案基本上是一个单行,真的。