Question

I have a txt file like this
$CHUNK_QTY = "50000";
$CLIENT = "hi all";
$CLIENT_CODE = "NMB";
$COMPOSER = "DIALOGUE";
$CONTROL_FILE_NAME = "NMBM725.XML";
$COPY_BASE = "01";
$CSITE = "NSH";
$DATA_TYPE = "MET";
$DIALOGUE_VERSION = "V7R0M624";
$DISABLE = "N";
$DPI = "300";
$DP_BAR_START = "A";
$DP_BAR_STOP = "Z";
$DUPLEX = "N";
$Dialogue_Version = "V7R0M624";
$EMAIL_ERROR = "Y";
$EMAIL_ON = "N";

I have many variables up to 500. I would like to access value for corresponding variable. For example if I want to access $DPI it should print 300 . How do I do that in perl. Any help will be appreciated. I would like something different than regex.

Thanks

Was it helpful?

Solution

Here's a quick example showing how to take lines in the format that you gave above and put them into a hash:

#!/usr/bin/env perl    

use strict;
use warnings;

my %vars;
while (my $line = <DATA>) {
  chomp $line;          # remove linebreak
  $line =~ s/^\$//;     # Optional: remove $ from start of variable name

  my ($key, $value) = $line =~ /^(\w+)\s*=\s*(.*)$/;
  $value =~ s/;$//;     # Remove trailing semicolon
  $value =~ s/^"//;     # Remove leading double-quotes
  $value =~ s/"$//;     # Remove trailing double-quotes
  $vars{$key} = $value;
} 

for my $key (sort keys %vars) {
  print "$key has value $vars{$key}\n";
}

print "CLIENT says $vars{CLIENT}\n";

__DATA__
$CHUNK_QTY = "50000";
$CLIENT = "hi all";
$CLIENT_CODE = "NMB";
$COMPOSER = "DIALOGUE";
$CONTROL_FILE_NAME = "NMBM725.XML";
$COPY_BASE = "01";
$CSITE = "NSH";
$DATA_TYPE = "MET";
$DIALOGUE_VERSION = "V7R0M624";
$DISABLE = "N";
$DPI = "300";
$DP_BAR_START = "A";
$DP_BAR_STOP = "Z";
$DUPLEX = "N";
$Dialogue_Version = "V7R0M624";
$EMAIL_ERROR = "Y";
$EMAIL_ON = "N";

There should be enough here to get you started, but you'll need to read up on how to open an actual file (instead of using the __DATA__ section as I did here) for yourself. I recommend checking perldoc open for examples and full details.

OTHER TIPS

Incorrect, wrong, bad, and dangerous way:

eval qx{cat filename.txt};
print "$DPI\n";

or

do "filename.txt";
print "$DPI\n";

so don't do it.

It is much better parse and untaint the file for example with regex...

If not want regex based solution, you at least can use the Safe.pm module:

use Safe;
my $sandbox = new Safe;
$sandbox->rdo( "filename.txt"  ) or die "safe problem $@";

#more safe now
do "filename.txt";
print "$DPI\n";

the rdo is like do but in safe environment, especially it can catch the $X = qx {rm -rf /}; constructions. If the file passed the rdo it probably can be do-ed.

Of course, the above is wrong too, because you cannot use use strict; as TLP already told. The best way is parsing the file.

And for regex based solution you can use:

use strict;
use warnings;
my $re = qr /^\s*\$(\w+)\s*=\s*"(.*)"\s*;\s*$/o;
my %conf = map { m/$re/;($1,$2) } grep {$re} <DATA>;
__END__
$CHUNK_QTY = "50000";
$CLIENT = "hi all";
$CLIENT_CODE = "NMB";
$COMPOSER = "DIALOGUE";
$CONTROL_FILE_NAME = "NMBM725.XML";
$COPY_BASE = "01";
$CSITE = "NSH";
$DATA_TYPE = "MET";
$DIALOGUE_VERSION = "V7R0M624";
$DISABLE = "N";
$DPI = "300";
$DP_BAR_START = "A";
$DP_BAR_STOP = "Z";
$DUPLEX = "N";
$Dialogue_Version = "V7R0M624";
$EMAIL_ERROR = "Y";
$EMAIL_ON = "N";

You can use do for a file to run it:

do "yourfile";
print $DPI;

However, if you are running under use strict, as you should, you'd need to first declare the variables with our:

use strict;
use warnings;

our $DPI; # plus any other variables you want to use
do "yourfile";
print $DPI;

You could use hashes, that way you could write the names and values into the hash list and retrieve them based on their names.

Here is a method to read the contents of a file and put the contents into the hash structure:

my $hash = ();
open FILE, "<", "stuff.txt" or die $!;

while(<FILE>)
{
    my @attr  = split(/=/);
    #this is actually a regexp, but you can read the data in any way you want

    my $key   = $attr[0];
    my $value = $attr[1];
    #only splitting up so that it becomes easier to read

    $hash{$key} = $value;#insert key and value  
}
close (FILE);
print 'Content of $CLIENT:'.$hash{'$CLIENT'};
print 'Content of $CHUNK_QTY:'.$hash{'$CHUNK_QTY'};

Contents of the file "stuff.txt"

$CLIENT="hi all"
$CHUNK_QTY="50000"
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top