使用包含不匹配大括号的文件

时间:2017-12-15 14:13:51

标签: file tcl curly-braces

我需要修改一个文件,其中包含几行不匹配的大括号,如:

  rmsd {
    atoms {
      atomsFile 
      atomsCol B
      atomsColValue 1
    }

所以,如果我这样做:

set fp [open "fpor.conf" r]
set file_data [read $fp]
close $fp
set confFile [split $file_data "\n"]

set inOut [open "us.in" w]

foreach line $inFile {
     if {[lindex $line 0] == "atomsFile"} {
        lappend line "us.pdb"
     }
     puts $inOut "$line"
}
close $inOut

脚本失败并显示错误: 列表中无与伦比的开放式大括号。有办法避免这种情况吗?

3 个答案:

答案 0 :(得分:2)

您将文件读入行列表,然后迭代这些行。你的错误是将行视为列表而不是字符串。这将对您有所帮助:

foreach line $confFile {
    set fields [regexp -all -inline {\S+} $line]
    if {[lindex $fields 0] eq "atomsFile"} { ...
  • 在这里,split不足以找到以空格分隔的单词,因为split会对单个字符进行拆分:

    % set line {      atomsFile }
          atomsFile 
    % split $line
    {} {} {} {} {} {} atomsFile {}
    

或者只是进行正则表达式匹配:

foreach line $confFile {
    if {[regexp {^\s*atomsFile} $line]} { ...

正如您所注意到的,您无法处理任何字符串,就好像它是一个列表一样。

% set line "no { match here"
no { match here
% lindex $line 0
unmatched open brace in list
% lindex [split $line] 0
no

答案 1 :(得分:1)

如果您打算按如下方式更新文件,

atomsFile us.pdb
然后,不是检查存在的列表索引,而是检查单词。

if {[regexp atomsFile $line]} {
    lappend line "us.pdb"
}

答案 2 :(得分:0)

如果文件内容不合适,最好将其视为仅文本。

set fp [open "fpor.conf" r]
set file_data [read $fp]
close $fp
set fp [open "us.in" w]
puts -nonewline $fp [regsub -line -all {^(\s*atomsFile.*)$} $file_data {\1us.pdb}]
close $fp

或更高级别:

package require fileutil

proc appendIt file_data {
    regsub -line -all {^(\s*atomsFile.*)$} $file_data {\1us.pdb}   
}

::fileutil::writeFile us.in [appendIt [::fileutil::cat fpor.conf]]

文档: closefileutil (package)openpackageprocputsreadregsubsetSyntax of Tcl regular expressions