从Tcl中的多个文件中读取特定数据



我正在编写一个TCL脚本来读取多个文件,并使用regexp在其中搜索包含特定单词的行。我从文件中找到了一样东西。但我需要修改脚本搜索多个东西在一个脚本打印项目在一个文件一起在一行,然后从另一个文件在第二行找到的项目。我写了这个

foreach fileName [glob  /home/kartik/tclprac/*/*] {
#   puts " Directories present are: [file tail $fileName]" 
set fp [open $fileName "r"]
while { [gets $fp data]>=0 } {
if {[regexp {set Date*} $data] | [regexp {set Channel* } $data] } {
#puts "file: [file dirname $fileName] data: $data"
set information "file: [file dirname $fileName] data: $data"
puts $information
set fp2 [open output.txt "a"]
puts $fp2 $information
}
}
}

现在我得到的输出为:

file: /home/kartik/tclprac/wire_3 data: set Date 02/08/2021 
file: /home/kartik/tclprac/wire_2 data: set Date 01/08/2021
file: /home/kartik/tclprac/wire_1 data: set Channel Disney 
file: /home/kartik/tclprac/wire_1 data: set Date 31/07/2021

我想要的是类似

的东西
file: /home/kartik/tclprac/wire_3 data: set Date 02/08/2021 
file: /home/kartik/tclprac/wire_2 data: set Date 01/08/2021 
file: /home/kartik/tclprac/wire_1 data: set Date 31/07/2021 set Channel Disney

在我看来,您想要将单个文件的结果收集到单行上,而不是为每个匹配行打印出一行(传统的grep工具方法),每行结果用空格分隔。

我们可以这样做,但是如果我们将代码分成几个过程(一个用于处理单个文件的内容,另一个用于处理整个工作),它会更清晰一些。

proc processFileContents {name contents accumulatorChannel} {
set interesting [lmap line [split $contents "n"] {
if {![regexp {set (?:Date|Channel) } $line]} {
# SKIP non-matching lines
continue
}
# Trim the matching lines
string trim $line
}]
# If we matched anything, print out
if {[llength $interesting]} {
set information "file: $name data: [join $interesting n]"
puts $information 
puts $accumulatorChannel $information
}
}
proc processFilesInDir {pattern accumulatorChannel} {
foreach fileName [glob -nocomplain -type f $pattern] {
set channel [open $fileName]
set contents [read $channel]
close $channel
processFileContents $fileName $contents $accumulatorChannel
}
}
set accum [open output.txt "a"]
processFilesInDir /home/kartik/tclprac/*/* $accum
close $accum

如果你使用的是旧版本的Tcl,没有lmap(8.5或之前),那么你可以用foreach来写(因为lmap实际上只是foreach的集合形式;唯一的区别是lmap使用一个隐藏的临时变量来进行累积):

proc processFileContents {name contents accumulatorChannel} {
set interesting {}
foreach line [split $contents "n"] {
if {![regexp {set (?:Date|Channel) } $line]} {
# SKIP non-matching lines
continue
}
# Trim the matching lines
lappend interesting [string trim $line]
}
# If we matched anything, print out
if {[llength $interesting]} {
set information "file: $name data: [join $interesting n]"
puts $information 
puts $accumulatorChannel $information
}
}

最新更新