如何使用tcl删除文件的特定内容
How to delete specific contents of file using tcl
我是 tcl 的新手,在开始我的项目之前,我正在研究基本示例以更好地理解。
如果有人能帮助或建议删除文件特定内容的最佳方法,我将不胜感激。
在我的例子中,我在 LogData.dat 文件中有一些数据,我想打开这个文件删除第 3 行,同时删除第一列(#Name、#Index#、#mspace)然后在完成更改后保存文件。
列数可能超过 5,但始终是第一个带有#Name、#Index#、#mspace 的列需要删除,第 3 行需要删除。
我想知道是否最好先删除第 3 行(去掉#mspace),然后将单词#Name、#Index 与正则表达式匹配,然后以某种方式删除#Name & #Index
我还需要记住,这些文件可能非常大 (100mb),并且会有多个文件,所以我需要循环这些文件,直到所有文件都被修改。因此需要避免任何内存问题,如果我必须快速读写这么大的文件。
如果有人能提供一些帮助或提供一个简单干净的示例,我们将不胜感激。
示例(精简版)如下所示。
#Name Length Width height Time
#Index m - - s
#mSpace 0 0 0 0
13.4112 0 0 0
13.411177 0 1.8827043e-007 0.001
13.411122 0 1.8827043e-007 0.002
我建议您阅读该文件并写入另一个文件,以便更轻松地遵循您自己的代码。你可以这样做一点:
# Open file for reading
set input [open "LogData.dat" r]
# Open file for writing
set output [open "newLogData.dat" w]
# This variable will help us know the line number
set ln 0
# Loop through each line of the file
while {[gets $input line] != -1} {
incr ln
if {$ln < 4} {
if {$ln < 3} {
# On lines 1 to 2, split the line on tab, remove the first
# element of the result list and join it back with tabs
set line [join [lreplace [split $line \t] 0 0] \t]
} else {
# Skip line 3 completely
continue
}
}
puts $output $line
}
close $input
close $output
你真的不需要正则表达式,上面是一个文件内容已经在变量中的例子。
您可以输入 file delete LogData.dat
和 file rename newLogData.dat LogData.dat
之类的内容来删除初始文件并使用旧文件的名称重命名新文件。
我将滑动 Jerry 的建议以从一个文件读取并写入另一个文件:
set input [open LogData.dat r]
set output [open newLogData.dat w]
这些字段似乎不是字符分隔的,因此 split
不会按预期工作。如果每一行都是正确的列表,字段中没有白色space,这不会造成任何问题。
如果第三行总是在第一个字段中有字符串 #mSpace
而其他行在第一个字段中没有它,我们就不需要计算行数。 (更新: 修复了 if
条件中的愚蠢拼写错误,抱歉。)
# Loop through each line of the file
while {[chan gets $input line] != -1} {
set data [lassign $line first]
if {$first ne "#mSpace"} {
chan puts $output $data
}
}
输出时,此代码会将字段之间的连续白色space字符压缩为单个space字符。
chan close $input
chan close $output
此代码从每一行中删除第一个字段,因为这似乎是您所要求的。重新阅读您的问题,现在看来您只想在前三行中将其取出。 更新代码:
# Loop through each line of the file
while {[chan gets $input line] != -1} {
set data [lassign $line first]
if {[string match #* $first]} {
if {$first ne "#mSpace"} {
chan puts $output $data
}
} else {
chan puts $output $line
}
}
文档:chan, if, lassign, open, set, while
(注:评论里的'Hoodiecrow'是我,我之前用的那个nick。)
我是 tcl 的新手,在开始我的项目之前,我正在研究基本示例以更好地理解。
如果有人能帮助或建议删除文件特定内容的最佳方法,我将不胜感激。
在我的例子中,我在 LogData.dat 文件中有一些数据,我想打开这个文件删除第 3 行,同时删除第一列(#Name、#Index#、#mspace)然后在完成更改后保存文件。
列数可能超过 5,但始终是第一个带有#Name、#Index#、#mspace 的列需要删除,第 3 行需要删除。
我想知道是否最好先删除第 3 行(去掉#mspace),然后将单词#Name、#Index 与正则表达式匹配,然后以某种方式删除#Name & #Index
我还需要记住,这些文件可能非常大 (100mb),并且会有多个文件,所以我需要循环这些文件,直到所有文件都被修改。因此需要避免任何内存问题,如果我必须快速读写这么大的文件。
如果有人能提供一些帮助或提供一个简单干净的示例,我们将不胜感激。
示例(精简版)如下所示。
#Name Length Width height Time
#Index m - - s
#mSpace 0 0 0 0
13.4112 0 0 0
13.411177 0 1.8827043e-007 0.001
13.411122 0 1.8827043e-007 0.002
我建议您阅读该文件并写入另一个文件,以便更轻松地遵循您自己的代码。你可以这样做一点:
# Open file for reading
set input [open "LogData.dat" r]
# Open file for writing
set output [open "newLogData.dat" w]
# This variable will help us know the line number
set ln 0
# Loop through each line of the file
while {[gets $input line] != -1} {
incr ln
if {$ln < 4} {
if {$ln < 3} {
# On lines 1 to 2, split the line on tab, remove the first
# element of the result list and join it back with tabs
set line [join [lreplace [split $line \t] 0 0] \t]
} else {
# Skip line 3 completely
continue
}
}
puts $output $line
}
close $input
close $output
你真的不需要正则表达式,上面是一个文件内容已经在变量中的例子。
您可以输入 file delete LogData.dat
和 file rename newLogData.dat LogData.dat
之类的内容来删除初始文件并使用旧文件的名称重命名新文件。
我将滑动 Jerry 的建议以从一个文件读取并写入另一个文件:
set input [open LogData.dat r]
set output [open newLogData.dat w]
这些字段似乎不是字符分隔的,因此 split
不会按预期工作。如果每一行都是正确的列表,字段中没有白色space,这不会造成任何问题。
如果第三行总是在第一个字段中有字符串 #mSpace
而其他行在第一个字段中没有它,我们就不需要计算行数。 (更新: 修复了 if
条件中的愚蠢拼写错误,抱歉。)
# Loop through each line of the file
while {[chan gets $input line] != -1} {
set data [lassign $line first]
if {$first ne "#mSpace"} {
chan puts $output $data
}
}
输出时,此代码会将字段之间的连续白色space字符压缩为单个space字符。
chan close $input
chan close $output
此代码从每一行中删除第一个字段,因为这似乎是您所要求的。重新阅读您的问题,现在看来您只想在前三行中将其取出。 更新代码:
# Loop through each line of the file
while {[chan gets $input line] != -1} {
set data [lassign $line first]
if {[string match #* $first]} {
if {$first ne "#mSpace"} {
chan puts $output $data
}
} else {
chan puts $output $line
}
}
文档:chan, if, lassign, open, set, while
(注:评论里的'Hoodiecrow'是我,我之前用的那个nick。)