使用包含不匹配大括号的文件
Working with file containing unmatched 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
脚本失败并出现错误:
列表中不匹配的左括号。有没有办法避免这种情况?
如果您打算按如下方式更新文件,
atomsFile us.pdb
然后,不检查存在的列表索引,只检查单词。
即
if {[regexp atomsFile $line]} {
lappend line "us.pdb"
}
您将文件读入行列表,然后迭代这些行。您的错误是将行视为列表而不是字符串。这将帮助您:
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
当文件的内容是一个不正确的列表时,最好将其视为纯文本。
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 {us.pdb}]
close $fp
或者,更高级一点:
package require fileutil
proc appendIt file_data {
regsub -line -all {^(\s*atomsFile.*)$} $file_data {us.pdb}
}
::fileutil::writeFile us.in [appendIt [::fileutil::cat fpor.conf]]
文档:
close,
fileutil (package),
open,
package,
proc,
puts,
read,
regsub,
set,
Syntax of Tcl regular expressions
我需要修改一个文件,其中包含几行带有不匹配大括号的行,例如:
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
脚本失败并出现错误: 列表中不匹配的左括号。有没有办法避免这种情况?
如果您打算按如下方式更新文件,
atomsFile us.pdb
然后,不检查存在的列表索引,只检查单词。
即
if {[regexp atomsFile $line]} {
lappend line "us.pdb"
}
您将文件读入行列表,然后迭代这些行。您的错误是将行视为列表而不是字符串。这将帮助您:
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
当文件的内容是一个不正确的列表时,最好将其视为纯文本。
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 {us.pdb}]
close $fp
或者,更高级一点:
package require fileutil
proc appendIt file_data {
regsub -line -all {^(\s*atomsFile.*)$} $file_data {us.pdb}
}
::fileutil::writeFile us.in [appendIt [::fileutil::cat fpor.conf]]
文档: close, fileutil (package), open, package, proc, puts, read, regsub, set, Syntax of Tcl regular expressions