如何使用tcl删除文件的特​​定内容

时间:2015-01-31 12:45:08

标签: regex tcl

我是tcl的新手,在开始我的项目之前,我正在通过基本的例子来获得一些很好的理解。

如果有人会帮助或建议删除文件特定内容的最佳方法,我将不胜感激。

在我的情况下,我在LogData.dat文件中有一些数据,我想打开这个文件删除第3行,同时删除第一列(#Name,#Index#,#mspace),然后保存更改后的文件。

列数可能超过5,但它始终是#Name,#Index#,需要删除的#mspace和需要删除的第3行的第一列。

我想知道首先删除第3行(除去#mspace)然后将单词#Name,#Index与regexp匹配然后以某种方式删除#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

2 个答案:

答案 0 :(得分:2)

我建议您阅读该文件并写入另一个文件,以便更轻松地按照您自己的代码。你可以这样做:

# 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之类的内容来删除初始文件,并使用旧名称重命名新文件。

答案 1 :(得分:0)

我会轻视Jerry的建议,即从一个文件中读取并写入另一个文件:

set input [open LogData.dat r]
set output [open newLogData.dat w]

这些字段似乎不是字符分隔的,因此split无法按预期工作。如果每一行都是一个在字段中没有空格的正确列表,这不会导致任何问题。

如果第三行在第一个字段中始终包含字符串#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
    }
}

在输出时,此代码会将字段之间的连续空白字符压缩为单个空格字符。

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
    }
}

文档:chaniflassignopensetwhile

(注意:评论中提及的&#39; Hoodiecrow&#39;是我,我之前使用过那个昵称。)