in tcl, how do I replace a line in a file?

24,041

Solution 1

for plain text files, it's safest to move the original file to a "backup" name then rewrite it using the original filename:

Update: edited based on Donal's feedback

set timestamp [clock format [clock seconds] -format {%Y%m%d%H%M%S}]

set filename "filename.txt"
set temp     $filename.new.$timestamp
set backup   $filename.bak.$timestamp

set in  [open $filename r]
set out [open $temp     w]

# line-by-line, read the original file
while {[gets $in line] != -1} {
    #transform $line somehow
    set line [string tolower $line]

    # then write the transformed line
    puts $out $line
}

close $in
close $out

# move the new data to the proper filename
file link -hard $filename $backup
file rename -force $temp $filename 

Solution 2

In addition to Glenn's answer. If you would like to operate on the file on a whole contents basis and the file is not too large, then you can use fileutil::updateInPlace. Here is a code sample:

package require fileutil

proc processContents {fileContents} {
    # Search: AA, replace: aa
    return [string map {AA aa} $fileContents]
}

fileutil::updateInPlace data.txt processContents

Solution 3

If this is Linux it'd be easier to exec "sed -i" and let it do the work for you.

Share:
24,041
n00b programmer
Author by

n00b programmer

Updated on June 14, 2020

Comments

  • n00b programmer
    n00b programmer almost 4 years

    let's say I opened a file, then parsed it into lines. Then I use a loop:

    foreach line $lines {}
    

    inside the loop, for some lines, I want to replace them inside the file with different lines. Is it possible? Or do I have to write to another temporary file, then replace the files when I'm done?

    e.g., if the file contained

    AA
    BB
    

    and then I replace capital letters with lower case letters, I want the original file to contain

    aa
    bb
    

    Thanks!