Conversion of CSV file to hash table using perl

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • pnsreee
    New Member
    • Apr 2007
    • 34

    Conversion of CSV file to hash table using perl

    Hi All,

    Please help me to convert csv file to a hash table with out using Text::CSV_XS , Text::CSV.

    The CSV file is a dynamic file.

    the fields are like this

    Numb,Name,Class ,Type,......

    201,Bazaar,b2,5 3,..........

    121,Raymond,y1, 02,...

    232,Robert,p1,0 4,............. ..



    Here first line is name of fields and remaing are values to corresponding fields
  • KevinADC
    Recognized Expert Specialist
    • Jan 2007
    • 4092

    #2
    what have you tried so far?

    Comment

    • pnsreee
      New Member
      • Apr 2007
      • 34

      #3
      Originally posted by KevinADC
      what have you tried so far?
      Im able to convert inot an array...but not possiable to hash

      Comment

      • KevinADC
        Recognized Expert Specialist
        • Jan 2007
        • 4092

        #4
        lets see the code you used to convert to an array....

        Comment

        • pnsreee
          New Member
          • Apr 2007
          • 34

          #5
          Originally posted by KevinADC
          lets see the code you used to convert to an array....

          using this i can get each column into an array

          my @myvar = `more +2 flat1.txt | cut -d "," -f $num` ;

          Comment

          • KevinADC
            Recognized Expert Specialist
            • Jan 2007
            • 4092

            #6
            thats not perl code. The example data you entered could be structured many different ways as a hash. You could read the file line by line and use the split() function to make a list of the fields, make one of the fields the hash key and the rest of the fields could be structured as an array or hash or just a single value. Assuming the first column/fields will be the hash keys:

            Code:
            my %hash = ():
            open(FH,'file.txt') or die "$!";
            while(<FH>){
               chomp;
               my @fields = split(/,/);
               $hash{$fields[0]} = ??;
            }
            close(FH);

            and ?? is whatever the value should be for the rest of the columns/fields.

            Comment

            • pnsreee
              New Member
              • Apr 2007
              • 34

              #7
              Originally posted by KevinADC
              thats not perl code. The example data you entered could be structured many different ways as a hash. You could read the file line by line and use the split() function to make a list of the fields, make one of the fields the hash key and the rest of the fields could be structured as an array or hash or just a single value. Assuming the first column/fields will be the hash keys:

              Code:
              my %hash = ():
              open(FH,'file.txt') or die "$!";
              while(<FH>){
                 chomp;
                 my @fields = split(/,/);
                 $hash{$fields[0]} = ??;
              }
              close(FH);

              and ?? is whatever the value should be for the rest of the columns/fields.


              Hi Kevin

              Thanks for your quick replay.

              Comment

              • larsvegas
                New Member
                • Oct 2008
                • 1

                #8
                Try that:

                ############### ############### ############### ############### ###########
                # Name : read_csv
                #
                # Description : Reads csv file into hash array
                #
                # In : csv file name, filed separation key (; in most cases)
                #
                # Out : hash array
                ############### ############### ############### ############### ###########
                sub read_csv {
                my $csv_file = shift;
                my $separator = shift;

                my %hash=();
                my @labels;
                my @lines;
                my $col_count = 0;
                my $row = 0;
                my ($line,$odd,$it em,$data);

                if (open(CSV,$csv_ file)) {

                while (<CSV>) {
                # remove leading and trailing spaces
                $_ = trim($_);
                #skip emty lines
                next if /^$/;
                # copy next line
                $line .= $_;

                # if the line has an odd number of double qoutes it will concatenate the
                # following lines until an od number of qoutes are encountered again.
                if ((not $odd and /^[^"]*"[^"]*(?>[^"]*"[^"]*"[^"]*)*[^"]*$/) or # Regexp: test if even number of double qoutes
                ($odd and /^[^"]*(?>[^"]*"[^"]*"[^"]*)*[^"]*$/)) { # Regexp: test if odd number of double qoutes
                $odd = 1;
                # keep new line
                $line .= " ";
                next;
                }
                # reset column counter
                $col_count = 0;
                # remove carriage if any and linefeed from end
                $line =~ s/\r?\n$//;
                # split on separator if followed by an odd number of double qoutes
                foreach $item (split /$separator(?=(? >[^"]*"[^"]*"[^"]*)*[^"]*$)/, $line, 100000) {

                # remove leading and trailing spaces
                $item = trim($item);
                # remove last new line
                $item =~ s/\s"$/"/;

                # skip first line of labels
                if ($row > 0) {
                $hash{$row}{$la bels[$col_count++]} = $item;
                } else {
                push (@labels,$item) ;
                }

                }
                $row++;
                undef $line;
                undef $odd;
                }
                close (CSV);
                } else {
                print_log("$csv _file: $!");
                die ("$csv_file: $!");
                }
                return (\@labels,\%has h);
                }

                Comment

                • nithinpes
                  Recognized Expert Contributor
                  • Dec 2007
                  • 410

                  #9
                  Originally posted by larsvegas
                  Try that:

                  }
                  larsvegas,
                  There is no point in replying to a post which is more than an year old!! Also, use code tags while posting your code in future.

                  Comment

                  • Icecrack
                    Recognized Expert New Member
                    • Sep 2008
                    • 174

                    #10
                    that's the funniest thing i have seen in age's,

                    and yes use code tags, 2nd we don't post full code.

                    Comment

                    Working...