Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Perl CSV module question...

Status
Not open for further replies.

Vallurupa

Programmer
Oct 17, 2001
38
US
Hi,

I am trying to read a CSV file having data as following format.

name=system,serialno=3234234,post=serial,src=dynamic,......

I have more that 10 values like above. I have to read them with perl and parse them and print at the command line in the following way. They have to be seperated and print as a table with equal order.

name serialno post src

system 3234234 serial dynamic

I could parse them and got the values in my array. Please help me in arrianging this way in perl.

Thanks in advance

Venkat.
vxprasad@yahoo.com
 
I would substitue the comma's for & symbols and feed the resulting string to CGI.pm

This gives you an easily accessible datastrucure that you can print out anyway you would like.

You could write your own CGI Args parsing routine but why bother, CGI.pm does this very well.
 
Hi siberian...

Thanks for the post. I am writing this script on linux. I have to show at command line. I am not using any cgi coading. Can I do the CGI.pm on linux. I am new to both linux and perl aswell. PLease help me..

Thanks
Venkat
 
CGI.pm is normally used for CGI processing but it has other uses as well.

Your datastructure of

arg=val,arg=val,arg=val

is the same as the CGI data structure which is

arg=val&arg=var&arg=val

So by substituting '&' for ',' you create a CGI data structure.

You can then feed this to the CGI.pm library (included standard on linux more likely then not, type 'perldoc CGI' to see if you have it installed) and manipulate it via that easy to use system.

#$string is the data you read from the file

$string =~ s/\,/\&/gsimx;
use CGI ;
my $data = new CGI( $string ) ;

print $data->param('arg1');
print $data->param('arg2');
..
..
..

 
name=system,serialno=3234234,post=serial,src=dynamic

ok... without CGI then

while(<>){
chomp;
@args = split(/,/);
foreach $field (@args){
$field =~ /=/;
$field_name = $`;
$field_data = $';
# do something with the field name and data
}
}


Mike

Want to get great answers to your Tek-Tips questions? Have a look at faq219-2884

It's like this; even samurai have teddy bears, and even teddy bears get drunk.
 
Thank you so much siberian and mike....

I am getting the parsed values in to my array. Now i have to display in the ordered way like take.. Same spacing..
But in my code if name is long or data is longit si showing uneven.
I should show like this

name serialno post src dsfasdfasd dsfasdfas

system 3234234 serial dynamic dsfasd dffsda

Here is my code....

!/usr/bin/perl
# This assembles multiline CSV files into records and then parses using
#

use CSV;
$dquote = &quot;\&quot;&quot;;
# these two variables are set once per *record* but span *lines*
$csvdata = &quot;&quot;;
$numq = 0;

while (<STDIN>) {

$pos = -1;
while (($pos = index($_, $dquote, $pos)) > -1) {
$pos++; # step over the double quote
$numq++;
};

$csvdata = $csvdata . $_; # linefeed preserved

if ( ! ($numq % 2) ) {
# now have complete record, process it
@fields = CSVsplit($csvdata);

print &quot;----------------------------------------------------------------------------\n&quot;,&quot; &quot;;
for ($i=0 ; $i<scalar(@fields); $i++) {
@fields1 = split /=/, $fields[$i];
print $fields1[0],&quot; &quot;;
};
# print &quot;\n&quot;,&quot;----------------------------------------------------------------------------\n&quot;,&quot; &quot;;

print &quot;\n&quot;,&quot; &quot;;
for ($j=0 ; $j<scalar(@fields); $j++) {
@fields2 = split /=/, $fields[$j];
print $fields2[1],&quot; &quot;;
};

print &quot;\n&quot;,&quot;\n&quot;;

# reset trans-loop iterator variables
$csvdata = &quot;&quot;;
$numq = 0;
};
exit;
}


Thanks
Venkat
 
You have two potential issues:

1) You are viewing your output on NONE mono-spaced fonts. if this is the case it will never line-up. In whatever app you are using to view this you want to use a mono-spaced font like 'Courier'. This will usually get you lined up correctly.

2) If you are actually having trouble with incosistent data sizing(and it appears you are) use printf or sprintf. This allows you to specify how many characters to print for each variable as well as some filler.

I bet Mike has the syntax on the top of his head :) I'd have to look it up.
 
Hi siberian,

I tried with

printf &quot;%-20s&quot;,$fields1[0]; It is working fine. But I still have small problem. If it exceeds the line width it is printing two lines for the names and 2 lines for the data. Not like the table. Here I have to find the line width and stop at the end of the line and start on the new line. Thanks for your help.

Venakt
 
An alternative is to read all the data in and as you populate each field into your data structure also update a new 'maxwidth' parameter.

Then when you generate output use 'maxwidth' to set all the %s values.

You need to know your largest value to prevent breakage.

John-
 
Thanks john... I am printing only 5 values now. I am trying for maxwidth parameter.

Venkat
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top