Perl Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming LanguagesPerl Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
Stop making mediocre tutorials.The best tutorials are video! Camtasia Studio makes it easy to create engaging, buzz-building screen videos at any size, in any popular format. Download the free trial!
  #61  
Old April 24th, 2008, 07:39 PM
electron_89 electron_89 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 83 electron_89 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 18 h 18 m 21 sec
Reputation Power: 2
So if i did this: (added the database info at top and if I release the comment and define the exact number of columns that should do it?)

Code:
use strict;
use warnings;
use Data::Dumper;
use CGI qw/:standard *table/;
use CGI::Carp qw/fatalsToBrowser/;
use DBI;

$db="";
$host="";
$port="";
$userid="";
$passwd="";
$connectionInfo="DBI:mysql:database=$db;$host:$port";

my $dbh = DBI->connect($connectionInfo,$userid,$passwd)
						or die("Cannot connect: $DBI::errstr\n");

print header, start_html, start_table;

my $file = 'parseMore.txt';

{
	local $/ = "\r\n"; #not for you
	open my $fh, "<", $file or die "Can't open $file: $!";
	my $header = <$fh>;
	chomp $header;
	my @head = split /\t/, $header;
	
	while (<$fh>) {
		chomp;
		my %row;
		@row{@head} = split /\t/;
		$row{'column3'} =~ s/"//g;

		print start_table;
		my @repeat = split /\n/, $row{'column3'};		
		foreach (@repeat) {
			my @three = split /,/, $_, 2;
			my @data = map {$row{$_} || undef} qw/column1 column2 column4 column5 column6 column7 column8 column9 column10/;
			@data = (@data, @three);
			print Tr(td(@data)) if $_ !~ /^\s*$/;
			#$sth->execute(@data);
		}
		print end_table;
	}
}

print end_html;

Last edited by electron_89 : April 24th, 2008 at 07:44 PM.

Reply With Quote
  #62  
Old April 24th, 2008, 07:44 PM
electron_89 electron_89 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 83 electron_89 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 18 h 18 m 21 sec
Reputation Power: 2
actually that causes problems. i added use DBI;
but still get compliation errors.

Reply With Quote
  #63  
Old April 24th, 2008, 07:55 PM
keath's Avatar
keath keath is offline
!~ /m$/
Dev Shed Frequenter (2500 - 2999 posts)
 
Join Date: May 2004
Location: Leawood, Kansas
Posts: 2,513 keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level) 
Time spent in forums: 1 Week 4 Days 9 h 9 m
Reputation Power: 527
Code:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use CGI qw/:standard *table/;
use CGI::Carp qw/fatalsToBrowser/;

=pod
	Print a standard html header.

	If you want to use Data::Dumper to print data into the browswer, 
	then switch to text mode:

	print header('text/text');
=cut

print header, start_html;

my $file = 'tsv_parse.tsv';

{
=pod
	Tell perl to expect Windows line endings
	Necessary because perl on the server is expecting Unix line endings
	
	The special variable $/ is set to the OS line ending by default
	If you override it, you need to do it with a local scope so you 
	don't ruin things for others.
	
	That's why this section appears within the indented bracket;
	it provides a scope for the $/
	
	Outside of the blocks, the value will revert to the default automatically
=cut

	local $/ = "\r\n";
	
	# open the file
	open my $fh, "<", $file or die "Can't open $file: $!";
	
=pod
	The first line of your file is a header
	I just grab it here to use as field definitions later.
	You wouldn't want to insert this line anyway
=cut
	my $header = <$fh>;
	chomp $header;
	# split the header row into individual names
	my @head = split /\t/, $header;
	
	while (<$fh>) {
=pod
	Remove the line ending with chomp;
	Because you changed $/ to Windows mode
	the chomp command will remove \r\n from the line end
	rather than just the normal \n it would have otherwise
	
	That's not all $/ did for us though.
	Without it, the <$fh> command would have stopped reading the line
	in column3, when it came to a \n character
=cut
		chomp;
=pod
	Define a hash
	Then use a hash slice to automatically fill it in
	the keys to the hash will be the column names from the header row
	and the values will be assigned to the correct positions
	
	print Dumper \%row to see
=cut
		my %row;
		@row{@head} = split /\t/;
		$row{'column3'} =~ s/"//g;
=pod
	When inserting into a database, there will be no need to print to a table obviously
	This is just for your enjoyment
=cut
		print start_table;
=pod
	We want to split column3 (if it's called column3
	Otherwise change this name
=cut
		my @repeat = split /\n/, $row{'column3'};
=pod
	if there are no newlines, the split will move the only value it sees
	into $repeat[0], so the array will still contain a single value
	and the next section will proceed for a single interation
=cut
		foreach (@repeat) {
=pod
	The default variable $_ contains values like: VISHAY BC COMPONENTS, 2222036 Rule Based Upgrades
	We will split them on space
	
	One thing not tested here is that there are actually two values produced
	Because of the limit, there will be no more than two, but it's possible you 
	could only have one
=cut
			my @three = split /,/, $_, 2;
=pod
	The row hash is not in a predictable order
	You have to put the values in a set order for the insert
	The map is an easy way.  It will map out the columns in the order in which they are named.
	Also, you only get the values you want.  I skipped column3 because we will add it manually.
=cut
			my @data = map {$row{$_} || undef} qw/column1 column2 column4 column5 column6 column7 column8 column9 column10/;
			@data = (@data, @three); # combine the arrays.  The split column three is added to the end
			print Tr(td(@data)) if $_ !~ /^\s*$/;
			#$sth->execute(@data);  # insert it
		}
		print end_table;
	}
}

print end_html;

You will have to show your code and the errors you receive.

Last edited by keath : April 24th, 2008 at 08:11 PM. Reason: removed the #not for you comment, which keeps creeping back in

Reply With Quote
  #64  
Old April 24th, 2008, 08:02 PM
electron_89 electron_89 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 83 electron_89 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 18 h 18 m 21 sec
Reputation Power: 2
Keath, that is very clear...thx!
I still don't understand where I can indicate the database information and my db tablename etc...
Can you show me in detail?

Reply With Quote
  #65  
Old April 24th, 2008, 08:05 PM
electron_89 electron_89 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 83 electron_89 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 18 h 18 m 21 sec
Reputation Power: 2
Some info: may be useful..

I have a total of 16 columns in my table in the db.
one is the number count, the other at the end is the date when it was imported.

Reply With Quote
  #66  
Old April 24th, 2008, 08:09 PM
keath's Avatar
keath keath is offline
!~ /m$/
Dev Shed Frequenter (2500 - 2999 posts)
 
Join Date: May 2004
Location: Leawood, Kansas
Posts: 2,513 keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level) 
Time spent in forums: 1 Week 4 Days 9 h 9 m
Reputation Power: 527
I don't have your database information. I created my own using postgres:
Code:
#!/usr/bin/perl -wT
use strict;
use CGI qw/:standard *table/;
use CGI::Carp qw/fatalsToBrowser/;
use DBI;

my $dbh = DBI->connect("dbi:Pg:dbname='test'", 'postgres', '', {'RaiseError'=>1}) or die "Unable to connect to db: $!";

$dbh->do('drop table some_stuff');
$dbh->do('create table some_stuff(column1 varchar(40),column2 varchar(40),column3 varchar(40),column4 varchar(40),column5 varchar(40),column6 varchar(40),column7 varchar(40),column8 varchar(40),column9 varchar(40),column10 varchar(40),columnU varchar(40))');

my $sth = $dbh->prepare('insert into some_stuff (column1, column2, column4, column5, column6, column7, column8, column9, column10, column3, columnU) values (?,?,?,?,?,?,?,?,?,?,?)');

print header, start_html;

my $file = 'tsv_parse.tsv';

{
	local $/ = "\r\n";
	open my $fh, "<", $file or die "Can't open $file: $!";
	my $header = <$fh>;
	chomp $header;
	my @head = split /\t/, $header;
	
	while (<$fh>) {
		chomp;
		my %row;
		@row{@head} = split /\t/;
		$row{'column3'} =~ s/"//g;

		print start_table;
		my @repeat = split /\n/, $row{'column3'};		
		foreach (@repeat) {
			my @three = split /, /, $_, 2;
			my @data = map {$row{$_} || undef} qw/column1 column2 column4 column5 column6 column7 column8 column9 column10/;
			@data = (@data, @three);
			if ($_ !~ /^\s*$/) {
				print Tr(td(@data));
				$sth->execute(@data);
			}
		}
		print end_table;
	}
}

print end_html;

and the insert worked:
Code:
test=# select * from some_stuff;
 column1 | column2 |       column3        | column4 | column5 | column6 | column7 | column8 | column9 | column10 |           columnu           
---------+---------+----------------------+---------+---------+---------+---------+---------+---------+----------+-----------------------------
 data1   | data2   | VISHAY BC COMPONENTS | data4   | data5   | data6   | data7   | data8   | data9   | data10   | 2222036 Rule Based Upgrades
 data1   | data2   | VISHAY BC COMPONENTS | data4   | data5   | data6   | data7   | data8   | data9   | data10   | 2222048 Rule Based Upgrades
 data1   | data2   | VISHAY BC COMPONENTS | data4   | data5   | data6   | data7   | data8   | data9   | data10   | 2222116 Rule Based Upgrades
 data1   | data2   | VISHAY BC COMPONENTS | data4   | data5   | data6   | data7   | data8   | data9   | data10   | 2222151 Rule Based Upgrades
(4 rows)

Reply With Quote
  #67  
Old April 24th, 2008, 08:15 PM
electron_89 electron_89 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 83 electron_89 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 18 h 18 m 21 sec
Reputation Power: 2
wow that was fast. i am going to try it now but question...
my file has 16 columns but the output shows 12...i looked at the code but couldnt' figure out where i can set the amount of columns to parse.

Reply With Quote
  #68  
Old April 24th, 2008, 08:19 PM
keath's Avatar
keath keath is offline
!~ /m$/
Dev Shed Frequenter (2500 - 2999 posts)
 
Join Date: May 2004
Location: Leawood, Kansas
Posts: 2,513 keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level) 
Time spent in forums: 1 Week 4 Days 9 h 9 m
Reputation Power: 527
You let perl parse the whole file. No need to try and limit it to certain columns.

When you are defining the data that you want to insert into the database, just name the columns you want:
Code:
my @data = map {$row{$_} || undef} qw/column1 column2 column4 column5 column6 column7 column8 column9 column10/;

Reply With Quote
  #69  
Old April 24th, 2008, 08:25 PM
electron_89 electron_89 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 83 electron_89 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 18 h 18 m 21 sec
Reputation Power: 2
Hmm... my original excel file had 16 columns.
so after reverting to tsv it should still retain 16 columns.
when they were parsed, that should make 17 columns because we split the two from that one cell.

when i run the script with the same tsv file, i see outputs and counted only 12 columns...so this is where i am confused.

hey Keath thx for the database code part.
it is very understandable...i am testing now...

Quote:
Originally Posted by keath
You let perl parse the whole file. No need to try and limit it to certain columns.

When you are defining the data that you want to insert into the database, just name the columns you want:
Code:
my @data = map {$row{$_} || undef} qw/column1 column2 column4 column5 column6 column7 column8 column9 column10/;

Reply With Quote
  #70  
Old April 24th, 2008, 08:32 PM
electron_89 electron_89 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 83 electron_89 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 18 h 18 m 21 sec
Reputation Power: 2
i had dumped the data successfully into the db =)
however, still problems with the other column data that is missing... i am looking at the code..trying to figure it out...

Reply With Quote
  #71  
Old April 24th, 2008, 08:34 PM
keath's Avatar
keath keath is offline
!~ /m$/
Dev Shed Frequenter (2500 - 2999 posts)
 
Join Date: May 2004
Location: Leawood, Kansas
Posts: 2,513 keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level) 
Time spent in forums: 1 Week 4 Days 9 h 9 m
Reputation Power: 527
Yes, they are still there, but if you don't name them, they won't be moved by this code into the @data array.
Code:
my @data = map {$row{$_} || undef} qw/column1 column2 column4 column5 column6 column7 column8 column9 column10 column11 column12 column13 column14 column15 column16/;

This was by no means the only way. Here's another:
Code:
foreach (@repeat) {
	my @three = split /, /, $_, 2;
	my @data = map {$row{$_} || undef} @head;
	$data[2] = $three[0];
	push @data, $three[1];
	if ($_ !~ /^\s*$/) {
		#print Tr(td(@data));
		$sth->execute(@data);
	}
}

Using @head to define the order ensures you will get every value; but you'll have to override the value of $data[2], because you don't want the original value there. You want the split.

Then you have to decide where you want the extra bit. I pushed it to the end.
Comments on this post
electron_89 agrees: Excellence here!

Reply With Quote
  #72  
Old April 24th, 2008, 08:36 PM
electron_89 electron_89 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 83 electron_89 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 18 h 18 m 21 sec
Reputation Power: 2
Keath!!! I got it! IT WORKS!!!!

You are not human!

Owe you a huge one!

Reply With Quote
  #73  
Old April 24th, 2008, 08:46 PM
keath's Avatar
keath keath is offline
!~ /m$/
Dev Shed Frequenter (2500 - 2999 posts)
 
Join Date: May 2004
Location: Leawood, Kansas
Posts: 2,513 keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level)keath User rank is Colonel (50000 - 60000 Reputation Level) 
Time spent in forums: 1 Week 4 Days 9 h 9 m
Reputation Power: 527
Cool. Since I'm not in L.A. to collect that meal, I'm headed to Wendy's. And for the blokes overseas, no that's not my girlfriend, unfortunately.

Reply With Quote
  #74  
Old April 24th, 2008, 08:49 PM
electron_89 electron_89 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 83 electron_89 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 18 h 18 m 21 sec
Reputation Power: 2
Haha..Wendy's has excellent burgers. If you were here I would treat you to some Kobe Beef or Highest-End Sushi

You Rock!

I'm Out!

Love this forum...where can Donate?


Quote:
Originally Posted by keath
Cool. Since I'm not in L.A. to collect that meal, I'm headed to Wendy's. And for the blokes overseas, no that's not my girlfriend, unfortunately.

Reply With Quote