如何使用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

codepag demo

你真的不需要正则表达式,上面是一个文件内容已经在变量中的例子。

您可以输入 file delete LogData.datfile 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。)