我正在尝试执行以下操作:
Prefix_2
替换为Prefix_999
Prefix_1
我可以做到第3点但是当涉及到替换名称时,我似乎无法将感兴趣的线分成元素,以便我可以用Prefix_2
替换Prefix_999
它总是取代整个感兴趣的行,如下所示,例如
Prefix_2.Var1 = 5124
将替换为Prefix_999
而不是Prefix_999.Var1 = 5124
文件Data.txt
Prefix_1.Var1 = 200
Prefix_1.Var2 = 0.3
Prefix_1.Var3 = 0.5
Prefix_1.Var4 = 0.25
Prefix_1.Var5 = 3
Prefix_1.Var6 = 36
Prefix_1.Var7 = 5612
Prefix_1.Var8 = 631
Prefix_1.Var9 = 102
Prefix_1.Var10 = 14
Prefix_1.Var11 = 3
Prefix_1.Var12 = 2
Prefix_2.Var1 = 5124
Prefix_2.Var2 = 876
Prefix_2.Var3 = 10.1
Prefix_2.Var4 = 11
我的代码:
set input [open "Data.txt" r]
set number 0
set var2 ""
while { [gets $input line] >= 0 } {
incr number
set sline [split $line "\n"]
set var1 [regexp {Prefix_2.Var1} $sline match]
if {$var1 == 1} {
set rVar1 [split $sline \s]
# check the length to index correctly for replacing
set rVar2 [llength $rVar1]
set rVar2 [lreplace $rVar2 0 0 Prefix_999.Var1]
}
}
close $input
答案 0 :(得分:1)
由于您没有编写文本过滤器,因此最好在更高级别上工作。
proc processLine {bufName line} {
upvar 1 $bufName buf
switch -regexp $line {
{^Prefix_1\.} {}
{^Prefix_2\.} {
lappend buf [regsub 2 $line 999]
}
default {
lappend buf $line
}
}
}
package require fileutil
set buf {}
fileutil::foreachLine line data.txt {
processLine buf $line
}
fileutil::writeFile data.txt [join $buf \n]
较低级open
- gets
- close
组合是语言核心的一部分;可以用来抽象掉这个组合的大部分用法的fileutil
包是Tcllib
的一部分,它是Tcl的伴随库。
我在这里使用您的规范,因为您的代码有点难以理解。
确定感兴趣的行
processLine
命令将接收参数line
中的每一行。 switch -regexp $line {...}
命令允许我按行前缀(或者不管怎样,标准可以是正则表达式可以表达的任何内容)对行进行分类。有三类线:以" Prefix_1"开头的那些,以" Prefix_2"开头的那些和所有其他线。我将它设置为一个默认操作,将行保存在持久缓冲区中(在命令中称为buf
,在其外部$bufName
:在我的代码中,两个名称都相同)。
将Prefix_2名称替换为Prefix_999
对于以" Prefix_2"开头的行,我跳过默认操作,而是保存修改后的行,其中第一次出现的2被999替换。
删除所有包含Prefix_1的行
只需跳过这些行的默认操作即可满足此要求。
打开文件阅读和拆分行
这由fileutil::foreachLine
自动完成。
将行保存到原始文件
我只是使用换行符加入缓冲区中的行并调用fileutil::writeFile
来更新文件。
ETA 没有upvar
行处理命令不必直接访问行缓冲区;相反,它可以简单地返回行(跳过的行是空字符串)。在这种情况下,需要在foreachLine
:
proc processLine line {
switch -regexp $line {
{^Prefix_1\.} {}
{^Prefix_2\.} {
regsub 2 $line 999
}
default {
return $line
}
}
}
package require fileutil
set buf {}
fileutil::foreachLine line data.txt {
set line [processLine $line]
if {$line ne {}} {
lappend buf $line
}
}
fileutil::writeFile data.txt [join $buf \n]
(我将这个版本评为劣等。)
文档:fileutil包,if,join,lappend,package,proc,regsub,{{ 3}},set,switch
答案 1 :(得分:0)
您可以将regsub
用于您的目的。
% set line {Prefix_2.Var1 = 5124}
Prefix_2.Var1 = 5124
% regsub {Prefix_2} $line {Prefix_999}
Prefix_999.Var1 = 5124
%