2010-05-12 127 views
4

比方说,我打开一个文件,然后解析成行。然后我用一个循环:,如何替换文件中的一行?

foreach line $lines {} 

内循环,对于一些行,我想替换他们用不同的线里面的文件。可能吗?还是必须写入另一个临时文件,然后在完成后替换文件?

例如,如果该文件包含

AA 
BB 

,然后我代替大写字母与小写字母,我想原来的文件包含

aa 
bb 

谢谢!

回答

8

为纯文本文件,它是最安全的原始文件移动到“备份”的名字,然后使用原来的文件名重写一遍:

更新:已修改的基础上多纳尔的反馈

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 
+1

这是更好地写在一个临时名称目录中的文件,然后做一个对'文件重命名的调用首先将旧文件移动到备份,然后将新文件移动到正确的名称。或者使用'file link -hard'来使备份和'文件重命名-force'移动到临时位置。 – 2010-05-13 08:01:27

+0

@唐纳,为什么呢? – 2010-05-13 10:15:48

+0

目标是尽可能长地保留旧文件的旧名称。使用硬链接/替换方法,替换是原子化的('rename()'是原子POSIX操作),并且总是有一些具有有效内容的文件的目标名称。这是一个旧的Unix黑客的伎俩。 :-) – 2010-05-13 12:30:55

5

另外以格伦的答案。如果你想在整个内容的基础上对文件进行操作并且文件不是太大,那么你可以使用fileutil :: updateInPlace。下面是一个代码示例:

package require fileutil 

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

fileutil::updateInPlace data.txt processContents 
1

如果这是Linux的它会更容易给exec“SED -i”,让它为你做的工作。

0

如果它是一个短文件你可以将其存储在一个列表:

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 
0
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 
相关问题