Prev: How to calculate "elapsed time" and "functions execution time" in log file?
Next: How to calculate "elapsed time" and "functions execution time"in log file?
From: Gerald W. Lester on 5 Aug 2010 17:38 Ahmad wrote: > Hi, > > I'm reading a configuration file passed to my tcl script. > > This configuration file, could contain paths to certain files using > environment variables: for example: > > file1_path $var1/$var2/${var3}/file.ext > > My script is parsing the config file, splitting each line to get key > and value (path) of entries. > > But passing this path directly to tcl nees to be first converted to > $env(...) > > I tried to use regsub to change all occurrences of cases like this, > using: > > set a {var1/$var2/${var3}/nonVar/file.ext} > set b [split $a '/'] > regsub -all {$([^/]+)} \$env(\1) $b > > But I don't know why it's always returning $evn( ) > > What is wrong in my expression? > > Is there any easier way to interpret shell env vars? Yes, depends on how safe you want to be. Least safe: Define a procedure which takes the file string (lets say file) which: 1) defines a local variable (e.g. var1) for each env var (e.g. ::env(var1)) 2) return a [subst -nocommand -nobackslash $file] Most safe: Create a safe interp with all commands hidden except subst. Define global variables (e.g. var1) for each env var (e.g. ::env(var1)) evaluate [list subst -nocommand -nobackslash $file] in the safe interp -- +------------------------------------------------------------------------+ | Gerald W. Lester, President, KNG Consulting LLC | | Email: Gerald.Lester(a)kng-consulting.net | +------------------------------------------------------------------------+
From: Andreas Leitgeb on 5 Aug 2010 19:26
Ahmad <ahmad.abdulghany(a)gmail.com> wrote: > set a {var1/$var2/${var3}/nonVar/file.ext} > set b [split $a '/'] > regsub -all {$([^/]+)} \$env(\1) $b > But I don't know why it's always returning $evn( ) There's a whole bunch of little mistakes... ;) -) first of all, you got the order of arguments for regsub wrong - you mixed up the input string with the substitute-pattern. -) the search-pattern doesn't escape the $, so it will never match anything (an unescaped dollar matches the end of string, so nothing could follow it for a match) You likely want the pattern {\$\{?([^/\}]+)\}?} instead, which also discard eventual braces from braced variables. -) you split for '/', but single quotes aren't special in tcl, so you split by the literal 3-chars-string: quote,slash,quote, which isn't found in $a, so you effectively get $a back, with another level of list quoting, just as if you had written: set b [list $a] -) If you fixed the split command to split by slashes alone, then the regexp-pattern would match everything after the first dollar, as there wouldn't be any slashes left. Better leave the split out completely, and apply the regsub on $a instead. -) finally, the \1 in \$env(\1) get's prematurely substed. regsub doesn't see the backslash-one sequence, but a character with code 1 (^A) Use {$env(\1)} instead. regsub -all {\$\{?([^/\}]+)\}?} $a {$env(\1)} Others have posted solutions boiling down to copying the environment variables into local variables of a procedure or even a new interpreter. That's perhaps the simpler approach, though not necessarily the better. And it takes a bit more than the naive approach, in order not to let the iteration variables interfere with the variables created, if e.g. there was a real envvar named "en" or "val". |