From: Mark Morgan on 21 Dec 2009 14:14 >Starting out by trying to understand the requirements here. You have a >file whose contents includes sequences of the form: > {@INPUTFILE FOOBAR.txt} >and each of those sequences needs to be replaced by the contents of >the file with the given name? That's correct. I really appreciate the input. As you might be able to tell this isn't my day job. :) I'll be able to give it a whirl later on and I'll send an even more grateful thank you email then! Thank you for your answer! Take care, Mark
From: Donald Arseneau on 21 Dec 2009 19:37 On Dec 21, 4:28 am, Mark Morgan <me.mor...(a)yahoo.com> wrote: > My basic issue is I've got a master text file that has the text of > other filenames scattered in it. I'm trying to substitute the > contents of the other files into the place where the filename is in > the master text file. Everything is in the same directory. > > The filename and the surrounding text that will need to be replaced is > this (quoted): "{@INPUTFILE example.txt}". The problem I'm having is > that I can't get it to substitute all of that text, all of the time. > Specifically if the file example.txt contains (quoted): "Example: > 300-45823" then it won't replace it. If it has "{Example: 300-45823} > then it will. > foreach textspiel [regexp -all -inline \ > {((\{@INPUTFILE)\s+\w+(.txt\}))} $data] { That doesn't make sense. The regexp is returning quadruplets of matches: the whole match, the outer () and the two inner (), so you should be skipping through the list 4 at a time (foreach {a b c d} [regexp..). I also see you have "." used where you intend "\." to match a literal period, not any one character. You aren't doing anything useful with the parentheses, so I suspect you misunderstand their function. Instead you should probably have used foreach {textspiel textfilename} [regexp -all -inline \ {\{@INPUTFILE\s+(\w+\.txt)\s+\}} $data] { > But, I think it must have to do with the brackets. It seems like when > the text file that's going to be substituted into the master file > contains bracketed text then the substitution goes forward. If not, > regexp finds it and sends it down through the code but regsub won't > substitute it. Yes, you suspect correctly (but your demonstration didn't even get that far). > regsub -all {$textspiel} $data {$contents} data; Here you are using literal plain text $textspiel as a regular expression meaning match the end of a line followed by "textspiel". Of course you meant "$textspiel" or $textspiel so that the value of the variable was used. But in that case you are still using plain (uncontrolled) text as a regular expression, which it is not. There are three solutions for that: 1) Don't use regsub: use string map instead. 2) Put escapes (backslashes) in front of all special charcters in the $textspiel text, using string map. Check re_syntax to make sure you cover every character that is special to regexp. 3) Tell regexp that the string is literal: regsub "***=$textspiel" $data {$contents} data Probably 1) is the best, but 3) is also convenient (but harder to decipher when you see the program later). (There is no reason to use -all because you are doing one item at a time with the foreach loop.) Donald Arseneau
From: Mark Morgan on 22 Dec 2009 07:24 > proc processTemplate string { > # This is exactly the replacement to make a string [subst]-safe > set s [string map {$ \\$ \[ \\\[ \\ \\\\} $string] > # Now convert the replacements to embedded commands > regsub -all {{@INPUTFILE (\w+\.txt)}} $s {[readFromFile \1]} s > # Process all the substitutions > return [subst $s] > } > # Simple read-a-file helper > proc readFromFile filename { > set f [open $filename] > set d [read $f] > close $f > return $d > # Use this instead if you want recursive template processing: > # return [processTemplate $d] > } OK, I've had some time to try to figure out what is happening here. I didn't have enough time to get it fully working but that's because of my data, I'm sure. I really, really appreciate ALL of the suggestions and posts. This is really helpful! I'm basically trying to prepare data in a TCL based program for use in a simple web app. This piece has been holding me up for quite a while. I can't tell you how nice it is to be so close to getting this part done!!! I'll get another chance tonight (hopefully) to work on this. #1 I figured I'd push my luck and ask if there's any simple way to catch the problem (common in my data) that the file (that comes after "@INPUTFILE") is missing. I was thinking that it'd be nice to substitute in some little note in the text file. My previous code had a little phrase that got put in there. #2 You can tell I didn't get too far, but would this be the proper implementation of the code you have written: set file [open $filename r+] set data [read $file] processTemplate $data puts $file $data close $file #3 I've got to get to my day job. I can't wait to get back to this, though! Take care, Mark
From: Donald Arseneau on 22 Dec 2009 19:29 On Dec 21, 4:37 pm, Donald Arseneau <a...(a)triumf.ca> wrote: > 3) Tell regexp that the string is literal: > regsub "***=$textspiel" $data {$contents} data I know you are on a track with [string map] followed by [eval], which is good. But for posterity I had better fix the bug above: I retained some other bogus braces from your original. It should be regsub "***=$textspiel" $data $contents data Donald Arseneau
From: slebetman on 22 Dec 2009 21:04 On Dec 22, 8:24 pm, Mark Morgan <admin.shortst...(a)gmail.com> wrote: > <snip> > > #2 You can tell I didn't get too far, but would this be the proper > implementation of the code you have written: > > set file [open $filename r+] > set data [read $file] > processTemplate $data > puts $file $data > close $file > close. If your intention is to append the processed text to the end of the unprocessed text then what you're doing is perfect. If on the other hand you intend to replace the unprocessed text with the processed text then you should seek to beginning of file: ... set data [processTemplate $data] seek $file 0 puts $file $data ...
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 Prev: Silent wrapping Next: tcl on multicore, what is the plan |