What would be the best way to read in the main.txt file and substitute
the contents of each text file for the actual string of the text
file's name?
I'm guessing I should go line by line through main.txt looking for the
phrase ".txt" back up until the first space to get the name and then
map the text of the file onto the filename.
Is there any example of this anywhere else or is there a better way to
do a search and replace through a text file?
Thank you for any help.
Mark
You could do it like this (untested):
# read in main.txt
set file [open main.txt]
set data [read $file]
close $file
set map [list]
# look for all substrings containing no spaces and ending in .txt
foreach filename [regexp -all -inline {\S*\.txt} $data] {
# check whether the file exists
if {[file exists $filename]} {
# read in the contents of the file; add them to the map
set file [open $filename]
set contents [read $file]
close $file
lappend map $filename $contents
}
}
# perform the mapping
set newdata [string map $map $data]
For this to work properly, your working directory would have to be the
one where main.txt resides. To be safe, you should probably also sort
$map so that longer filenames come first (if you had a file file.txt
and another one called otherfile.txt and file.txt is earlier in the
list, it will get substituted first; every instance of otherfile.txt
will be changed to other<contents of file.txt>). In 8.6, you could
sort the list like this (also untested):
proc sortbylength {a b} {
return [expr {[string length $a] - [string length $b]}]
}
set map [lsort -index 0 -stride 2 -decreasing -command sortbylength
$map]
Hope that helps.
-Aric
Just realized that the code I provided may create duplicate entries in
the map. To fix that, replace this line:
foreach filename [regexp -all -inline {\S*\.txt} $data] {
with these:
foreach filename [lsort -unique \
[regexp -all -inline {\S*\.txt} $data]] {
Thank you again! Please take a look at my next post to see where this
ended up and what my new problem is. I'll put the code in that post,
as well.
Sincerely,
Mark