Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Replacing environment variables

by loris (Hermit)
on Oct 17, 2006 at 13:42 UTC ( #578767=perlquestion: print w/ replies, xml ) Need Help??
loris has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

I'm sure I have asked this before, but I haven't been able to find where, so apologies for possibly repeating myself.

I have a file that contains environment variables. I want to create a new file in which the environment variables have been expanded. I could obviously get the template file line by line, look for things that look like environment variables, look these up in the %ENV hash, and replace the variable with the value if found. E.g.

use strict; use warnings; my $file = shift; my $undefinedVars = 0; open(FILE,$file); while (<FILE>) { if (/(\$[^\/\n\t]*)/) { my $var = $&; my $key = $var; substr($key, 0, 1) = ""; my $val = $ENV{$key}; if (defined($val)) { my $line = $_; $line =~ s/\$//g; $line =~ s/$key/$val/g; print $line; } else { $undefinedVars++; } } else { print $_; } } close(FILE); if ($undefinedVars > 0) { print "ERROR: There were $undefinedVars undefined variables!\n"; }

This input looks (something) like this:

bigcompany.product.part.widgit=$WIDGIT bigcompany.product.part.battery=$BATTERY bigcompany.product.part.frobnicator=$FROBNICATOR bigcompany.product.part.blorpdata=$BLORP/data

But I feel there must be a simpler way. Any ideas?

Thanks,

loris

Update 1: Added code

Update 2: Added input

Update 3: Added missing case to input


"It took Loris ten minutes to eat a satsuma . . . twenty minutes to get from one end of his branch to the other . . . and an hour to scratch his bottom. But Slow Loris didn't care. He had a secret . . ."

Comment on Replacing environment variables
Select or Download Code
Re: Replacing environment variables
by mantra2006 (Hermit) on Oct 17, 2006 at 13:54 UTC
    Hey
    The following two nodes might help you...
    http://www.perlmonks.org/?node_id=105795 http://www.perlmonks.org/?node_id=135922
    Thanks & Regards
    Sridhar
      You can make these linkable by writing [id://105795] like this: Environment Variables.

      And even rename them by writing [id://135922|Another node about Environment Variables]: Another node about Environment Variables.

      -- Hofmator

      Code written by Hofmator and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

      I don't really see how either of these nodes is relevant to the problem, other than that they happen to have the words "Environment Variables" in their title. It sounds like the real question is how to perform substitution of placeholders for variables in text, where in this case the collection of values happens to be %ENV. There are some modules for this such as Text::Template though I personally have not used them.

      Hello Sridhar,

      Thanks for replying, but as Errto points out, neither of the nodes you mention has any relevance to my problem.

      The update to my original post shows how I am currently dealing with the situation and may help you to understand what I am trying to do.

      loris


      "It took Loris ten minutes to eat a satsuma . . . twenty minutes to get from one end of his branch to the other . . . and an hour to scratch his bottom. But Slow Loris didn't care. He had a secret . . ."
Re: Replacing environment variables
by shmem (Canon) on Oct 18, 2006 at 10:00 UTC
    Good thing you updated your post with code. May we have a look at a sample input file too?
    if (/(\$[^\/\n\t]*)/) {

    What if the presumed variable is $f.`rm -rf $ENV{HOME}`? Oops. Lotsa space now..

    my $var = $&; my $key = $var; substr($key, 0, 1) = "";

    You capture your match with () and then use $&? And what do you have $var for? Why not $key = $1?

    Leave the the $ out of your capturing parens. That way you haven't got to strip it with substr.

    I'd write your loop as

    while(<FILE>) { if (my ($key) = /\$(\w+)/) { defined($ENV{$key}) and s/\$$key/$ENV{$key}/ or $undefinedVars++; } print; }

    but it's usefulness depends on the input file...

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

      Thanks for your reply. I have updated the OP with some sample input, which is, as you see, rather simple. I realised that the capturing the $ and then removing it is a bit silly, but when I moved the $ out of the capturing brackets, the match failed, so obvioulsy I have to escape the $ in some other way. You are right of course about not then needing two variables, one with the $ and one without.

      loris


      "It took Loris ten minutes to eat a satsuma . . . twenty minutes to get from one end of his branch to the other . . . and an hour to scratch his bottom. But Slow Loris didn't care. He had a secret . . ."
        while (<DATA>) { # match any dollar followed by a number # of non whitespaces (unicode safe) # and replace it by then corresponding # environment variable if ( s/\$(\P{IsSpace}+)/$ENV{$1}/ ) { $undefinedVars++ unless $ENV{$1}; } print; } if ( $undefinedVars > 0) { print "\n\nERROR: There were $undefinedVars undefined variables!\n +"; } __DATA__ bigcompany.product.part.path=$PATH bigcompany.product.part.widgit=$WIDGIT bigcompany.product.part.battery=$BATTERY bigcompany.product.part.frobnicator=$FROBNICATOR


        holli, /regexed monk/

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://578767]
Approved by Hue-Bond
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (15)
As of 2014-09-16 14:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (31 votes), past polls