我需要更新文件中的日期。因此,我正在搜索当天的行(#define __VERSION_DAY 23
)并拼命尝试更新它。
while {([gets $fp_Vers line] >= 0)} {
if { [string match -nocase "#define*__VERSION_DAY*" $line] } {
# Get the current day
set day [clock format $systemTime -format {%d}]
set line [split $line]
# Replace the old value
set line [lreplace $line 2 $day]
puts $fp_Vers $line
}
}
它将以下内容放在文件{#define} __VERSION_DAY
的末尾。我不明白......
1)为什么周围有括号定义
2)为什么缺少当天(即16)的价值。
感谢您的贡献!
答案 0 :(得分:0)
通过在getActivity().setTitle("title");
等Tcl shell中运行命令,您可以轻松找出问题所在。强烈建议这样做,以避免逃跑并做一些没有意义的事情。在下文中,命令(以tkcon
开头的行与结果混合。
%
将字符串拆分为列表时,字符串表示会更改,以便以后可以重新生成列表,因此% set line {#define __VERSION_DAY 23}
#define __VERSION_DAY 23
set day 16
16
% set line [split $line]
{#define} __VERSION_DAY 23
周围的大括号(否则将是无效的列表项)。
#define
set line [lreplace $line 2 $day]
{#define} __VERSION_DAY
命令采用以下参数:lreplace
list
(索引)first
(索引)last
(零个或多个元素替换范围用)。 ?element ...?
(16)的内容被解释为您想要替换为任何内容的范围中的最后一个索引。
请改为尝试:
day
关于更新文件中的日期字段,最好的选择可能是这样做:
% set line [join [lreplace [split $line] 2 2 $day]]
#define __VERSION_DAY 16
注意:不要直接输出set day 16
set f [open $filename]
set lines [split [string trim [read $f]] \n]
close $f
set result {}
set tag {#define __VERSION_DAY }
set pattern [string map {{ } *} $tag]
foreach line $lines {
if {[string match -nocase $pattern $line]} {
lappend result $tag$day
} else {
lappend result $line
}
}
set f [open $filename2 w]
puts -nonewline $f [join $result \n]
close $f
,因为引用变量的内容是为了保留列表附加行创建的列表结构。通过使用换行符连接行,结构将更改为平面文本,该文本在输出中起作用。
或者,使用Tcllib中的$result
,
fileutil
请注意,策略基本相同。第一个解决方案使用列表追加行进入变量,然后在其中打印连接文本。第二种解决方案是直接打印每一行。没有什么可以阻止您使用直接打印的低级package require fileutil
set day 16
set tag {#define __VERSION_DAY }
set pattern [string map {{ } *} $tag]
set f [open $filename2 w]
::fileutil::foreachLine line $filename {
if {[string match -nocase $pattern $line]} {
puts $f $tag$day
} else {
puts $f $line
}
}
close $f
- open
- read
解决方案或带有行列表的close
解决方案附加到变量中。
文档: close, fileutil (package), foreach, if, join, lappend, lreplace, open, package, puts, read, set, split, string
答案 1 :(得分:0)
问题是split
正在添加您不期望的引用,因为它满足其他情况下有意义的Tcl列表序列化的其他规则。在这种情况下,最简单的解决方法是切换到使用regsub
来执行替换。正则表达式绝对是锋利的工具,但无论如何它们有时也是完全正确的方法。
# Factor a few bits out for convenience
# The RE pattern we're looking for.
set VERSION_RE {(#define\s+_VERSION_DAY\s*).+}
# Get the current day as a replacement pattern
set dayReplacement [clock format $systemTime -format {\1%d}]
while {[gets $fp_Vers line] >= 0} {
if {[regsub $VERSION_RE $line $dayReplacement line]} {
# If we did the replacement, write the new value out
puts $fp_Vers $line
}
}
我怀疑您可能需要seek
或chan truncate
重置您要写入的位置,但这是您的问题。
这是有效的,因为当regsub
与变量写入参数一起使用时,其Tcl结果是执行的替换次数。没有-all
开关,那实际上是一个布尔值:是否找到(并替换)了模式?