2017-12-15 5 views
2

Ich brauche eine Datei mit mehreren Zeilen mit unerreichten Klammern wie zu ändern:Arbeiten mit Datei mit unübertroffenen Klammern

rmsd { 
    atoms { 
     atomsFile 
     atomsCol B 
     atomsColValue 1 
    } 

Also, wenn ich dies tun:

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 

Das Skript mit dem Fehler fehlschlägt: nicht übereinstimmende offene Klammer in der Liste. Gibt es eine Möglichkeit, dies zu vermeiden?

Antwort

1

Wenn Ihre Absicht ist es, die Datei zu aktualisieren, wie folgt

atomsFile us.pdb 

dann, statt für den Listenindex der Anwesenheitskontrolle, überprüfen nur das Wort.

heißt

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

Das tut genau das, was ich brauche. Danke vielmals! – kbr85

2

Sie die Datei in eine Liste von Zeilen lesen, dann iterieren Sie über die Zeilen. Ihr Fehler besteht darin, die Zeile wie eine Liste anstatt einer Zeichenfolge zu behandeln. Dies wird Ihnen helfen:

foreach line $confFile { 
    set fields [regexp -all -inline {\S+} $line] 
    if {[lindex $fields 0] eq "atomsFile"} { ... 
  • Hier ist split unzureichend, um die durch Leerzeichen getrennte Wörter zu finden, weil split Splits auf einzelne Zeichen:

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

Oder einfach passender Regex:

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

Wie Sie bemerkt haben, können Sie keine beliebige Zeichenfolge verarbeiten, als ob es sich um eine Liste handelt.

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

Wenn der Inhalt einer Datei eine falsche Liste ist, ist es besser, nur als Text zu behandeln.

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 

oder, ein wenig mehr auf hohem Niveau:

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]] 

Dokumentation: close, fileutil (package), open, package, proc, puts, read, regsub, set, Syntax of Tcl regular expressions