【问题标题】:How to look for the difference between two large files in tcl?如何在tcl中查找两个大文件之间的区别?
【发布时间】:2014-06-15 12:13:43
【问题描述】:

我有两个文件,其中的一些内容可能在这两个文件中是通用的。 (比如说文件A.txt和文件B.txt) 这两个文件都是排序文件。 我需要得到文件A.txtB.txt的区别,即一个文件C.txt,除了两者的共同内容外,其内容都是A。

我使用了典型的搜索和打印算法,即从A.txt 中取出一行,在B.txt 中搜索,如果找到,则在C.txt 中不打印任何内容,否则在C.txt 中打印该行。 但是,我正在处理包含大量内容的文件,因此会引发错误:failed to load too many files。 (虽然它适用于较小的文件)

任何人都可以提出更有效的获取C.txt 的方法吗? 要使用的脚本:仅限 TCL!

【问题讨论】:

  • 你的“仅限 tcl”限制太糟糕了:这正是 comm 的用途。

标签: file file-io compare tcl


【解决方案1】:

首先,too many files 错误表明您没有关闭通道,可能在B.txt 扫描仪中。解决这个问题可能是您的第一个目标。如果你有 Tcl 8.6,试试这个帮助程序:

proc scanForLine {searchLine filename} {
    set f [open $filename]
    try {
        while {[gets $f line] >= 0} {
            if {$line eq $searchLine} {
                return true
            }
        }
        return false
    } finally {
        close $f
    }
}

但是,如果其中一个文件足够小以合理地放入内存中,则最好将其读入哈希表(例如字典或数组):

set f [open B.txt]
while {[gets $f line]} {
    set B($line) "any dummy value; we'll ignore it"
}
close $f

set in [open A.txt]
set out [open C.txt w]
while {[gets $in line]} {
    if {![info exists B($line)]} {
        puts $out $line
    }
}
close $in
close $out

要高效得多,但取决于B.txt 是否足够小。

如果A.txtB.txt 都太大了,您最好分阶段进行某种处理,在中间将内容写入磁盘。这变得相当复杂!

set filter [open B.txt]
set fromFile A.txt

for {set tmp 0} {![eof $filter]} {incr tmp} {
    # Filter by a million lines at a time; that'll probably fit OK
    for {set i 0} {$i < 1000000} {incr i} {
        if {[gets $filter line] < 0} break
        set B($line) "dummy"
    }

    # Do the filtering
    if {$tmp} {set fromFile $toFile}
    set from [open $fromFile]
    set to [open [set toFile /tmp/[pid]_$tmp.txt] w]
    while {[gets $from line] >= 0} {
        if {![info exists B($line)]} {
            puts $to $line
        }
    }
    close $from
    close $to

    # Keep control of temporary files and data
    if {$tmp} {file delete $fromFile}
    unset B
}
close $filter
file rename $toFile C.txt

警告!我没有测试过这段代码……

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-16
    • 2013-10-30
    • 1970-01-01
    相关资源
    最近更新 更多