在 Tcl 中,如何逐行读入文件并找到字符串列表(来自另一个文件),然后在行后附加##
In Tcl, how to read in file by line and find a list of string (from another file) then append the line with a ##
我需要能够逐行读取文件并找到一组字符串(来自另一个文件),这些字符串以字符串加上字符集({ 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
strng412
我想在列出的每一项之后得到##..
提前致谢。`
这是否解决了您的问题?
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
命令,我们已重新定义该命令以识别相关关键字并使用 [=16] 打印完整的调用([info level 0]
) =]前缀,如果它们在列表中,否则只按原样打印调用。
文档:chan, foreach, if, info, join, open, proc, puts, regexp, set, source, split, unknown, while
这是另一个镜头:
while {[gets $fh line] != -1} {
set first [lindex [split [string trimleft $line]] 0]
puts [format "%s%s" [expr {$first in $list ? "##" : ""}] $line]
}
找到行中的第一个单词,并检查它是否是 $list 中的一个元素。
我需要能够逐行读取文件并找到一组字符串(来自另一个文件),这些字符串以字符串加上字符集({ 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
strng412
我想在列出的每一项之后得到##.. 提前致谢。`
这是否解决了您的问题?
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
命令,我们已重新定义该命令以识别相关关键字并使用 [=16] 打印完整的调用([info level 0]
) =]前缀,如果它们在列表中,否则只按原样打印调用。
文档:chan, foreach, if, info, join, open, proc, puts, regexp, set, source, split, unknown, while
这是另一个镜头:
while {[gets $fh line] != -1} {
set first [lindex [split [string trimleft $line]] 0]
puts [format "%s%s" [expr {$first in $list ? "##" : ""}] $line]
}
找到行中的第一个单词,并检查它是否是 $list 中的一个元素。