469,267 Members | 1,029 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,267 developers. It's quick & easy.

Conversion of CSV file to hash table using perl

34
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,53,..........

121,Raymond,y1,02,...

232,Robert,p1,04,...............



Here first line is name of fields and remaing are values to corresponding fields
Apr 21 '07 #1
9 15620
KevinADC
4,059 Expert 2GB
what have you tried so far?
Apr 21 '07 #2
pnsreee
34
what have you tried so far?
Im able to convert inot an array...but not possiable to hash
Apr 21 '07 #3
KevinADC
4,059 Expert 2GB
lets see the code you used to convert to an array....
Apr 21 '07 #4
pnsreee
34
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` ;
Apr 21 '07 #5
KevinADC
4,059 Expert 2GB
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:

Expand|Select|Wrap|Line Numbers
  1. my %hash = ():
  2. open(FH,'file.txt') or die "$!";
  3. while(<FH>){
  4.    chomp;
  5.    my @fields = split(/,/);
  6.    $hash{$fields[0]} = ??;
  7. }
close(FH);

and ?? is whatever the value should be for the rest of the columns/fields.
Apr 21 '07 #6
pnsreee
34
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:

Expand|Select|Wrap|Line Numbers
  1. my %hash = ():
  2. open(FH,'file.txt') or die "$!";
  3. while(<FH>){
  4.    chomp;
  5.    my @fields = split(/,/);
  6.    $hash{$fields[0]} = ??;
  7. }
close(FH);

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


Hi Kevin

Thanks for your quick replay.
Apr 23 '07 #7
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,$item,$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}{$labels[$col_count++]} = $item;
} else {
push (@labels,$item);
}

}
$row++;
undef $line;
undef $odd;
}
close (CSV);
} else {
print_log("$csv_file: $!");
die ("$csv_file: $!");
}
return (\@labels,\%hash);
}
Oct 1 '08 #8
nithinpes
410 Expert 256MB
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.
Oct 1 '08 #9
Icecrack
174 Expert 100+
that's the funniest thing i have seen in age's,

and yes use code tags, 2nd we don't post full code.
Oct 1 '08 #10

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

5 posts views Thread by Koncept | last post: by
19 posts views Thread by Johnny Google | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.