n00b programmer
n00b programmer

Reputation: 2701

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

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!

Upvotes: 4

Views: 27576

Answers (6)

Ross
Ross

Reputation: 1

For the next poor soul that is looking for a SIMPLE tcl script to change all occurrences of one word to a new word, below script will read each line of myfile and change all red to blue then output the line to in a new file called mynewfile.

    set fin "myfile"
    set fout "mynewfile"

    set win  [open $fin  r]
    set wout [open $fout w]

    while {[gets $win line] != -1} {
       set line [regsub {(red)} $line blue] 
       puts $wout $line
    }

    close $win
    close $wout

Upvotes: 0

Mallikarjunarao Kosuri
Mallikarjunarao Kosuri

Reputation: 1111

set fileID [open "lineremove.txt" r] 
set temp [open "temp.txt" w+] 
while {[eof $fileID] != 1} { 
    gets $fileID lineInfo 
    regsub -all "delted information type here" $lineInfo "" lineInfo 
    puts $temp $lineInfo 
} 
file delete -force lineremove.txt 
file rename -force temp.txt lineremove.txt 

Upvotes: 0

Jack
Jack

Reputation: 11

If it's a short file you can just store it in a list:

set temp ""

#saves each line to an arg in a temp list
set file [open $loc]
foreach {i} [split [read $file] \n] {
    lappend temp $i
}
close $file

#rewrites your file
set file [open $loc w+]
foreach {i} $temp {
    #do something, for your example:
    puts $file [string tolower $i]
}
close $file

Upvotes: 0

eemz
eemz

Reputation: 1211

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

Upvotes: 1

Hai Vu
Hai Vu

Reputation: 40723

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

Upvotes: 6

glenn jackman
glenn jackman

Reputation: 246817

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 

Upvotes: 9

Related Questions