2

Let's say I have a configuration file.

Config.csv

Server,Properties
"so-al-1","48989"
"so-al-3","43278"
"so-al-5","12345"

I need to use a perl script to retrieve the server and properties from the file in order to use the varible's values in my script. Also our client server doesn't want us to install any modules.

So how do I read this document in variables without using a module?

open(FILE,"Config.csv");
undef($/); #sucks the entire file in at once
while(<FILE>){
    (@words)=split(/\s+/);  
}
close FILE;

for (@words){
    s/[\,|\.|\!|\?|\:|\;]//g; #removed punctuation
    $word{$_}++;
}

for (sort keys %word){
    print "$_ occurred $word{$_} times\n";
}

I did try the above but it doesn't put it to a hash that I wanted.

Edited: I copied the code too fast and missed a line.

Edited: I just found out that there's a question like this in StackOverflow already. How can I parse quoted CSV in Perl with a regex?

Community
  • 1
  • 1
LynxLee
  • 321
  • 1
  • 6
  • 17
  • 1
    It looks like you have found snippets that do things like you want, but they aren't being used together correctly. May I ask: why don't you want to use modules? Parsing a csv is difficult and error prone without the easily used Text::CSV. Finally what is it you are trying to achieve? Get key-value configuration pairs (as your question suggests) or find the number of instances of unique words in the file as your code suggests? – Joel Berger Feb 23 '11 at 04:13
  • The major errors in your code show that you aren't proficient in Perl, which is fine. However you aren't even reading the same .csv file that you mention. How could you expect this code to work? – Joel Berger Feb 23 '11 at 04:21
  • Apologies for that, I copied the code a little too fast when I was working on something else. I only wanted to use the variable in another perl script. Parsing this csv to a hash would do just fine. – LynxLee Feb 23 '11 at 05:23

2 Answers2

2

Following the usual warning of "you should use a CSV module", this works:

#!/usr/bin/env perl
use warnings;
use strict;

my $header_str=<DATA>;
chomp $header_str;
my @header=$header_str =~ /(?:^|,)("(?:[^"]+|"")*"|[^,]*)/g;
my %fields;
my @temp;
my $line;

while($line=<DATA>){
    chomp $line;
    @temp = $line =~ /(?:^|,)("(?:[^"]+|"")*"|[^,]*)/g;
    for (@temp) {
        if (s/^"//) { 
            s/"$//; s/""/"/g;
        }
     }

     $fields{$temp[0]}=$temp[1];
}

print "$_\t\t" for (@header);
print "\n";
print map { "$_\t\t$fields{$_}\n" } sort keys %fields;

__DATA__
Server,Properties
"so-al-1","48989"
"so-al-3","43278"
"so-al-5","12345"

Output:

Server      Properties      
so-al-1     48989
so-al-3     43278
so-al-5     12345
dawg
  • 98,345
  • 23
  • 131
  • 206
  • When you find yourself typing out things like "/(?:^|,)("(?:[^"]+|"")*"|[^,]*)/"`, it's time to reconsider using a module. – socket puppet Feb 23 '11 at 05:02
  • @socket puppet: **>>I<<** would use a module, but the OP stated `no modules`! – dawg Feb 23 '11 at 05:06
  • Wow.. that's very complicated. I guess that's why modules are so important. Thanks. Ingenius coding. – LynxLee Feb 23 '11 at 05:34
0
#!/usr/bin/perl
use warnings;
use strict;

while (<DATA>) {
    chomp;
    next unless my($key,$value) = split /,/;
    s/^"//, s/"$// for $key, $value;
    print "key=$key value=$value\n";
}

__DATA__
Server,Properties
"so-al-1","48989"
"so-al-3","43278"
"so-al-5","12345"
tadmc
  • 3,714
  • 16
  • 14
  • This will split on commas inside of protected quoted fields. ie, `"don't, split", inside quotes` would be 3 fields. Once again -- why you should use a CSV module... – dawg Feb 23 '11 at 05:09