使用tcl查找并替换两个不同文件中的字符串?

时间:2017-02-17 02:25:55

标签: tcl

我有两个文件如下:

+ FILE1.TXT

1.3.1   abc
1.3.2   def
...

+ FILE2.TXT

abc  , value x value y
def  , value a value b
...

我希望 替换 abc file2.txt 中的第一次出现 1.3.1 file1.txt 中,因此file2.txt的结果应为:

+ FILE2.TXT

1.3.1  , value x value y
1.3.2  , value a value b

我正在使用TCL,我坚持这个:

set fileid1 [open "file1.txt" r+]
set fileid2 [open "file2.txt" r+]

set buffer1 [read $fileid1];
set buffer2 [read $fileid2];
set dataline1 [split $buffer1 "\n"]
set dataline2 [split $buffer2 "\n"]


foreach line $dataline2 {

}


close $fileid1
close $fileid2

3 个答案:

答案 0 :(得分:0)

以下是一种方法:

注意:如果file1.txt和file2.txt很大,这可能不是最佳选择,因为它一次性读取所有数据。可以稍微改变该方法以从每个文件一次读取一行。

$ cat replace.tcl
proc getReplaceMap {fileName} {
    set fd [open $fileName]
    set data [read $fd]
    close $fd

    array set replaceMap {}
    foreach line [split $data "\n"] {
        set line [string trim $line]
        if {$line eq ""} {
            continue
        }
        set replaceMap([lindex $line 1]) [lindex $line 0]
    }
    return [array get replaceMap]
}

proc getUpdatedLine {line replaceMap} {
    array set replacement $replaceMap
    set lineElements [split $line]
    foreach element [array names replacement] {
        set index [lsearch $element $lineElements]
        if {$index != -1} {
            set lineElements [lreplace $lineElements $index $index $replaceMap($element)]
        }
    }
    return [join $lineElements]
}

proc getUpdatedContents {fileName replaceMap} {
    set fd [open $fileName]
    set data [read $fd]
    close $fd

    set newData {}
    foreach line [split $data "\n"] {
        lappend newData [getUpdatedLine $line $replaceMap]
    }
    return [join $newData "\n"]
}

# Main begins here
set replaceMap [getReplaceMap file1.txt]
set newContents [getUpdatedContents file2.txt $replaceMap]
puts $newContents
# Now write to file
set fd [open file2.txt w]
puts $fd $newContents
close $fd


$

执行输出:

$ tclsh replace.tcl
abc , value x value y
def , value a value b

sharad$ cat file2.txt
abc , value x value y
def , value a value b

$

答案 1 :(得分:0)

# read the first file, store data in an array
set fh [open file1.txt r]
array set values {}
while {[gets $fh line] != -1} {
    regexp {(\S+)\s+(\S+)} $line -> value key
    set values($key) $value
}
close $fh

# read the second file, transform it, and write to a new file
set fh [open file2.txt r]
set fout [file tempfile tmpfilename]
while {[gets $fh line] != -1} {
    regexp {(\S+)} $line -> firstword
    if {[info exists values($firstword)]} {
        regsub "(?q)$firstword" $line $values($firstword) line
    }
    puts $fout $line
}
close $fh
close $fout

# backup the second file, and replace it with the new data
file rename file2.txt file2.txt~
file rename $tmpfilename file2.txt

之后

$ cat file2.txt
1.3.1  , value x value y
1.3.2  , value a value b

答案 2 :(得分:0)

将密钥和替换值加载到字典中:

package require fileutil

foreach {val key} [::fileutil::cat file1.txt] {
    dict set replacements $key $val
}

遍历另一个文件,查找关键字并替换它们:

set result {}
::fileutil::foreachLine line file2.txt {
    set key [regexp -inline {^\S+} $line]
    if {[dict exists $replacements $key]} {
        lappend result [regsub ^$key $line [dict get $replacements $key]]
    }
}
::fileutil::writeFile file3.txt [join $result \n]

fileutil包是Tcl,Tcllib标准库的一部分。

文档: dictfileutil (package)ifjoinlappendlreversepackageregexpregsubset{*} (syntax)Syntax of Tcl regular expressions