【问题标题】:How to delete specific contents of file using tcl如何使用 tcl 删除文件的特​​定内容
【发布时间】:2015-03-30 20:42:39
【问题描述】:

我对 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

【问题讨论】:

  • tl;dr -- 请同时显示输入和期望的输出

标签: regex tcl


【解决方案1】:

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

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

【讨论】:

  • 嗨,杰瑞,感谢您的回复,并让它看起来更轻松。这正是我想要做的,而且还让我对下一步做什么有了很好的了解……谢谢,这非常有帮助。
【解决方案2】:

我会刷 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

(注意:cmets中提到的'Hoodiecrow'是我,我之前用过那个昵称。)

【讨论】:

  • 嗨,Hoodiecrow,感谢您的回复。你和杰瑞都向我展示了如何以不同的方式编辑文件。非常感谢你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-05
  • 1970-01-01
  • 2012-09-22
  • 1970-01-01
  • 2019-02-23
  • 1970-01-01
  • 2013-11-04
相关资源
最近更新 更多