LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-15-2009, 01:06 PM   #1
VeeDubbs
Member
 
Registered: Feb 2006
Location: Wisconsin
Distribution: SuSe 10. Ubuntu
Posts: 47

Rep: Reputation: 15
Perl Help...


Hi All -

This will hopefully be fairly easy to answer as I know almost nothing about perl. I have a script that reads a file, manipulates it and sends it as an attached csv file in an e-mail. The part I need help with is as follows:

Code:
for $i(0..$#fields) {
        $accounts .= "\"$fields[$i][0]\", \"$fields[$i][2]\", \"$fields[$i][1]\", \"$fields[$i][3]\"\n";
}
The attached file varies in length everyday depending on how large the original file is.

I need help with two things here.

1) Is it possible to put headers in the very first row of the csv file? So row one will always be the same and then row two and on will be the data.

2) Currently, the fields have quotation marks around them. How can I have the fields printed but remove the quotes? I thought I removed the quotes one time and none of the fields got printed after that.

Thanks for any help!
 
Old 10-15-2009, 02:02 PM   #2
Telemachos
Member
 
Registered: May 2007
Distribution: Debian
Posts: 754

Rep: Reputation: 60
A few thoughts:
  • You should use a CSV module, rather than reinventing the wheel. Text::CSV is one obvious choice.
  • You can easily print the headers as the first line. Simply save them as a scalar (say $headers), and then do this before you start to print the rest of the rows to the file.
    Code:
    print $out_fh "$headers\n";
    That will print the $headers line to the filehandle $out_fh. You will need to have created and opened that filehandle first.
  • Can you show your data or how you're getting your data into the @fields array? It's hard to say much about the quotations problem without seeing the data itself.
 
Old 10-15-2009, 10:47 PM   #3
VeeDubbs
Member
 
Registered: Feb 2006
Location: Wisconsin
Distribution: SuSe 10. Ubuntu
Posts: 47

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by Telemachos View Post
A few thoughts:
  • You should use a CSV module, rather than reinventing the wheel. Text::CSV is one obvious choice.
  • You can easily print the headers as the first line. Simply save them as a scalar (say $headers), and then do this before you start to print the rest of the rows to the file.
    Code:
    print $out_fh "$headers\n";
    That will print the $headers line to the filehandle $out_fh. You will need to have created and opened that filehandle first.
  • Can you show your data or how you're getting your data into the @fields array? It's hard to say much about the quotations problem without seeing the data itself.
Thanks Telemachos!

Here's the full code. It was written by someone else many years ago.

Code:
#!/usr/bin/perl
#

use MIME::Lite;
use Text::ParseWords;

my $MAX = 'user@domain.com';
my $MAILHOST = 'host.domain.com';
my $USERNAME = 'Mailman';

# Check the program's arguments
if(@ARGV != 1) {
        print "Usage: GoogleFromNovell.pl <account file>\n";
        exit;
}

# Read fields from ARGV[0] file
my(@fields, $line, $i);
open(FILE, $ARGV[0]);

$i = 0;
for $line(<FILE>) {
    for ($line) {
        s/^\s+//;
        s/\s+$//;
    }
    @{$fields[$i]} = &parse_line(',', 0, $line);
    $i++;
}

close(FILE);

# Make sure to send via smtp
MIME::Lite->send("smtp", "$MAILHOST");

# Email to mmcgrath
my $msg = MIME::Lite->new(
        From    =>"$USERNAME <$USERNAME\@host.domain.com>",
        To      =>"$MAX",
        Subject =>"Google Mail User Accounts - " . localtime(),
        Type    =>"multipart/mixed"
        );

# Message Body
$msg->attach(Type       =>"TEXT",
        Data    =>"Google Mail User Accounts - " . localtime() . "\n"
        );

# Actual account list (as an attachment)
my $accounts = "";

for $i(0..$#fields) {
        $accounts .= "\"$fields[$i][0]\", \"$fields[$i][2]\", \"$fields[$i][1]\", \"$fields[$i][3]\"\n";
}

$msg->attach(Type       =>"text/plain",
        Filename        =>"Google Mail User Accounts - " . localtime() . ".csv",
        Disposition     =>"attachment",
        Data    =>"$accounts"
        );

# Send the message
$msg->send;
And here's what the data looks like from the file I'm getting.

Code:
"jsmith","Smith","John","796630",,,"A","796630","XXXXX9999","1982-07-02","53333"
"jsmith1","Smith","Joe","268426",,,"A","268426","XXXXX9999","1961-12-18","53333"
"jsmith2","Smith","Jeremy","762238",,,"A","762238","XXXXX9999","1963-03-04","53333"
Let me know what you think. Or if you need more data.
 
Old 10-15-2009, 11:19 PM   #4
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,359

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
The reason the orig programmer did that was in case of fields that have commas in them; defensive programming. It produces a nice consistent 'safe' csv file.
If you can guarantee(!) those fields will never have commas in them, then change that line to

Code:
$accounts .= "$fields[$i][0], $fields[$i][2], $fields[$i][1], $fields[$i][3]\n";
Basically remove any \" sequences.


Do header as per Telemachos.
 
Old 10-16-2009, 10:38 AM   #5
VeeDubbs
Member
 
Registered: Feb 2006
Location: Wisconsin
Distribution: SuSe 10. Ubuntu
Posts: 47

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by chrism01 View Post
The reason the orig programmer did that was in case of fields that have commas in them; defensive programming. It produces a nice consistent 'safe' csv file.
If you can guarantee(!) those fields will never have commas in them, then change that line to

Code:
$accounts .= "$fields[$i][0], $fields[$i][2], $fields[$i][1], $fields[$i][3]\n";
Basically remove any \" sequences.


Do header as per Telemachos.
Thanks for the help everyone!

I've made the changes and will check results tomorrow morning! I'll post back!

Thanks again!
 
Old 10-17-2009, 09:53 PM   #6
VeeDubbs
Member
 
Registered: Feb 2006
Location: Wisconsin
Distribution: SuSe 10. Ubuntu
Posts: 47

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by VeeDubbs View Post
Thanks for the help everyone!

I've made the changes and will check results tomorrow morning! I'll post back!

Thanks again!
Here's the code I used:

Code:
for $i(0..$#fields) {
        $accounts .= "username,first name,last name,password\n;"
        "$fields[$i][0],$fields[$i][2],$fields[$i][1],$fields[$i][3]\n";
}
All I got in my csv file was the first row of headers. After reviewing the code I noticed there was a semi-colon ending both lines. I've removed the one from the first line but will not see the results until Monday as the script doesn't run on Sunday. Does that sound like it would do the trick? As I do not know Perl, I'm only assuming that that is what caused my problem.

Or should I really consider using the print $out_fh "$headers\n"; as suggested above?

Thanks!

Last edited by VeeDubbs; 10-17-2009 at 09:54 PM.
 
Old 10-17-2009, 10:15 PM   #7
Telemachos
Member
 
Registered: May 2007
Distribution: Debian
Posts: 754

Rep: Reputation: 60
Quote:
Originally Posted by VeeDubbs View Post
Here's the code I used:

Code:
for $i(0..$#fields) {
        $accounts .= "username,first name,last name,password\n;"
        "$fields[$i][0],$fields[$i][2],$fields[$i][1],$fields[$i][3]\n";
}
Where did the "username,first name, last name, password\n" part come from? Based on your earlier code and what Chrism suggested, I would have thought you wanted this:

Code:
for $i(0..$#fields) {
    $accounts .= "$fields[$i][0],$fields[$i][2],$fields[$i][1],$fields[$i][3]\n";
}
 
Old 10-17-2009, 10:25 PM   #8
Telemachos
Member
 
Registered: May 2007
Distribution: Debian
Posts: 754

Rep: Reputation: 60
Quote:
Originally Posted by VeeDubbs View Post
Here's the code I used:

Code:
for $i(0..$#fields) {
        $accounts .= "username,first name,last name,password\n;"
        "$fields[$i][0],$fields[$i][2],$fields[$i][1],$fields[$i][3]\n";
}
Where did the "username,first name,last name,password\n" part come from? Based on your earlier code and what Chrism suggested, I would have thought you wanted this:

Code:
for $i(0..$#fields) {
    $accounts .= "$fields[$i][0],$fields[$i][2],$fields[$i][1],$fields[$i][3]\n";
}
Edit: Now I see what happened. Your $accounts variable is what later fills the Data portion of your email. You put the headers into that and then assigned the actual rows & fields to nothing. Hence, they didn't get printed.

Try this maybe:

Code:
# Actual account list (as an attachment)
my $accounts = "username,first name,last name,password\n";

for $i(0..$#fields) {
    $accounts .= "$fields[$i][0],$fields[$i][2],$fields[$i][1],$fields[$i][3]\n";
}
If I'm reading the script correctly, that should (1) set $accounts to the headers line and then (2) add the csv rows to $accounts inside the for loop.

Last edited by Telemachos; 10-17-2009 at 10:27 PM.
 
Old 10-20-2009, 09:33 AM   #9
VeeDubbs
Member
 
Registered: Feb 2006
Location: Wisconsin
Distribution: SuSe 10. Ubuntu
Posts: 47

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by Telemachos View Post
Try this maybe:

Code:
# Actual account list (as an attachment)
my $accounts = "username,first name,last name,password\n";

for $i(0..$#fields) {
    $accounts .= "$fields[$i][0],$fields[$i][2],$fields[$i][1],$fields[$i][3]\n";
}
If I'm reading the script correctly, that should (1) set $accounts to the headers line and then (2) add the csv rows to $accounts inside the for loop.
Thanks Telemachos!

That did it!!!
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: Installing Eclipse, the Epic Perl plugin and my first Perl GUI program LXer Syndicated Linux News 0 05-08-2009 06:41 PM
RHEL4u2 perl localtime() call issues (perl & glibc) Brad.Scalio@noaa.gov Linux - Enterprise 3 01-23-2007 09:27 PM
perl(Cwd) perl(File::Basename) perl(File::Copy) perl(strict)....What are those? Baldorg Linux - Software 1 11-09-2003 08:09 PM
chrooting apache v2 (php, ssl, perl support) ; perl configuration markus1982 Linux - Security 3 01-26-2003 06:15 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:23 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration