我有一个巨大的文件。我需要找到包含模式 abc_x 的行并将其值 0.34 替换为增加值的 10%。然后将整个文件(带有替换值)复制到一个新文件中。我是 Tcl 的新手,请告诉我该怎么做。提前致谢。
问问题
51 次
1 回答
1
这包括三个关键阶段:
读入旧文件。
更新内存中的数据。
写出新文件。
第一阶段和第三阶段非常标准:
set f [open input.txt]
set data [read $f]
close $f
set f [open output.txt "w"]
puts -nonewline $f $data
close $f
所以现在只需要在内存中进行转换。对此的最佳答案取决于您使用的 Tcl 版本。在所有当前的生产版本中,最好将数据拆分为行并对其进行迭代,检查行是否匹配,如果匹配,则执行转换。
set lines {}
foreach line [split $data "\n"] {
if {[matchesPattern $line]} {
set line [updateLine $line]
}
lappend lines $line
}
set data [join $lines "\n"]
好的,在上面的代码中,matchesPattern
并且updateLine
是真实代码的替代品,可能如下所示:
if {[regexp {^(\s*abc_x\s+)([\d.]+)(.*)$} $line -> prefix value suffix]} {
# Since we matched the prefix and suffix, we must put them back
set line $prefix[expr {$value * 1.1}]$suffix
}
将所有这些部分组合在一起可以得到:
set f [open input.txt]
set data [read $f]
close $f
set lines {}
foreach line [split $data "\n"] {
if {[regexp {^(\s*abc_x\s+)([\d.]+)(.*)$} $line -> prefix value suffix]} {
set line $prefix[expr {$value * 1.1}]$suffix
}
lappend lines $line
}
set data [join $lines "\n"]
set f [open output.txt "w"]
puts -nonewline $f $data
close $f
在 8.7 中,您将能够更简洁地编写更新:
set data [regsub -all -line -command {^(\s*abc_x\s+)([\d.]+)} $data {apply {{-> prefix value} {
# Since we matched the prefix, we must put it back
string cat $prefix [expr {$value * 1.1}]
}}}]
(变得比这更短确实需要一个支持后视的 RE 引擎;Tcl 的标准引擎不支持。)
于 2021-11-15T19:47:19.350 回答