0

我需要能够逐行读取文件并找到一组字符串(来自另一个文件),这些字符串以字符串加上一组字符(例如({ somedata }))然后将带有##的行附加到该块。

这是我到目前为止所拥有的:

set mydir <path to my dir>
#file name file.txt with content:
~>cat file.txt
Strng00  {
   some data 
}

Strng021  {
   some data 
}

Strng02  {
   some data 
}

Strng03  {
   some data 
}

Strng_dt  {
   some data 
}

Strng01 {
   some data 
}
Strng02  {
   some data 
}

Strng03  {
   some data 
}

Strng_dt  {
   some data 
}

Strng42  {
   some data 
}

Strng412 
-- 
set list { Strng01 Strng02 Strng03 Strng_dt Strng42 } # May be read in the list from another file which needs to be matched
set fileIn [lindex $argv 0]
set fileInId  [open $mydir/file.txt r]
set appendLine 0
foreach item $list {
    set j 0
    while {[gets $fileInId line ] != -1} {
        if [regexp  -all -line $item $line] { set appendLine 1 } 
        if $appendLine {
            if [regexp {^\s*\}\s*$} $line] { set appendLine 0 }   
            set line "## $line"    
        }
        puts $line
    }
set j 1
}

结果仅显示列表的第一个条目:

Strng00 
Strng021 
Strng02 
Strng03 
Strng_dt 
##Strng01  {
##   some data  
##}

Strng02 
Strng03 
Strng_dt 
Strng42 

字符串 412

我想在列出的每个项目之后得到##。提前谢谢。`

4

2 回答 2

0

这能解决你的问题吗?

set list { Strng01 Strng02 Strng03 Strng_dt Strng42 }
set fileInId  [open $mydir/file.txt r]

while {[gets $fileInId line ] != -1} {
    if {[regexp -line [join $list |] $line]} {
        set line "## $line"    
    }
    puts $line
}

编辑:处理更新的规范。

这是一种方法;它利用了文件中的行匹配 Tcl 命令调用语法这一事实。

proc unknown {cmd args} {
    set list { Strng01 Strng02 Strng03 Strng_dt Strng42 }
    if {$cmd in $list} {
        foreach line [split [info level 0] \n] {
            puts "## $line"
        }
    } else {
        puts [info level 0]
    }
}

source file.txt

它的工作原理是这样的:source在文件上使用意味着 Tcl 解释器尝试使用每一行的关键字作为命令名,并将{ ... }部分作为参数。由于关键字不是现有的命令,解释器将调用交给unknown命令,我们重新定义了命令以识别相关关键字并打印完整的调用 ( [info level 0]),如果它们在列表中,则带有##前缀,否则只打印按原样调用。

文档:chan , foreach , if , info , join , open , proc , puts , regexp , set , source , split , unknown , while

于 2016-02-12T07:34:31.593 回答
0

这是另一种看法:

while {[gets $fh line] != -1} {
    set first [lindex [split [string trimleft $line]] 0]
    puts [format "%s%s" [expr {$first in $list ? "##" : ""}] $line]
}

这会找到该行中的第一个单词,并检查它是否是 $list 中的一个元素。

于 2016-02-12T18:17:35.947 回答