If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

 
Go Back  dBforums > Data Access, Manipulation & Batch Languages > Perl and the DBI > Creating files using CSV delimiters

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 05-23-07, 16:14
PCheung PCheung is offline
Registered User
 
Join Date: May 2007
Posts: 2
Creating files using CSV delimiters

I have been trying to create a fixed length “Name and Address” file made up of fixed fields. (Typically an old fashion mainframe file) and the input data is via the keyboard. For this example only the name fields maybe between 1 and 15 characters long only and if a longer input stream is entered then it is to be truncated

I do not know how to put the CSV field delimiter in and I not sure if there is anything special when writing this type of record as I haven’t got that far.
I've just got lost

################################################## ##
#!/usr/bin/perl
# Enter Given Name
A05010:
print "Enter Given Name (Maximum 15 Characters),\n";
open ($Customer=<STDIN>);
@Customer=/(.{15})/g;
print $Customer pack("$Customer15", $Customer);
print 'is this correct?';
print "\n";
print 'enter Y or N';
print "\n";
chomp ($Reply = <STDIN>);
goto A05010 if ($Reply eq "N" or $Reply eq "n");
################################################## #
# SHOW ME WHAT HAPPENED
################################################## #
print "\n";
print '$Customer = ', $Customer;
print "\n";
################################################## #
# Enter Family Name
A05020:
print " Enter Family Name (Maximum 15 Characters),\n";
open ($Customer=<STDIN>);
@Customer=/(.{15})/g;
print $Customer pack("$Customer15", $Customer);
print 'is this correct?';
print "\n";
print 'enter Y or N';
print "\n";
chomp ($Reply = <STDIN>);
goto A05020 if ($Reply eq "N" or $Reply eq "n");
################################################## #
# SHOW ME WHAT HAPPENED
################################################## #
print '$Customer = ', $Customer;
print "\n";
Reply With Quote
  #2 (permalink)  
Old 05-24-07, 04:03
KevinADC KevinADC is offline
Registered User
 
Join Date: Feb 2006
Posts: 56
Where are you learning perl from? I haven't seen "goto" in a perl script in more than 10 years. You want to use substr() for the truncating. But your code has other problems.

http://perldoc.perl.org/functions/substr.html
Reply With Quote
  #3 (permalink)  
Old 07-03-07, 00:18
sco08y sco08y is offline
Registered User
 
Join Date: Oct 2002
Location: Baghdad, Iraq
Posts: 697
Looking at your code:

Code:
 #!/usr/bin/perl
The "shebang" line (because # is a sharp and ! is a bang) has to be the first line. It's optional; you can always execute your script with perl scriptname.pl. The only reason to have a shebang line is if you want your script to be executable. If you don't know what chmod +x does, don't bother with it.

Code:
open	($Customer=<STDIN>);
Here's what you're telling Perl:

Code:
<STDIN>     Read a line from standard input, STDIN.
$Customer=...  Assign that value to the scalar variable $Customer
open (...)  This is almost certainly not doing what you intended. It's opening a file whose name is the line you read from STDIN and associating that open file with a file handle of the same name.
Here's what you probably mean:

Code:
$Customer = <STDIN>
STDIN is already open for you when your script runs.

Code:
 	@Customer=/(.{15})/g;
Okay, here's a big perl trap beginners run into. $Customer and @Customer are two completely different variables. $Customer is a "scalar", which basically means it takes one simple value like a number or a string. (Perl figures out which automatically.) @Customer is an array, which means it holds multiple values.

It gets worse: $Customer[5] means the sixth value (since perl arrays are zero-based (but this can be changed (but don't do that))) of the array @Customer. There is a certain logic to it, but it's confusing enough for people that they're changing it in perl 6.

Next problem: your regular expression is going to match something that has a *minimum* of 15 characters, not a maximum. What you want is this:

Code:
use strict; # If this complains too much, try use strict 'vars' instead.
my($Customer); # Declares your variable. Do it this way until you learn more.
cust_input: print "Enter family name (15 char max)\n";
$Customer = <STDIN>;
chomp $Customer; # gets rid of the line break at the end.
unless($Customer =~ /^.{0,15}$/) {
    print "Family name too long.\n";
    goto cust_input;
}
Notice a few differences in the match statement:

1. I use =~ instead of =. The = sign means "assign a value." The =~ means "do a match against this value."

2. I added ^ and $. These match the beginning and end of the line. Regular expressions are great but they can be tricky, so it's good to read perlretut and perlre.
Reply With Quote
  #4 (permalink)  
Old 07-03-07, 00:34
sco08y sco08y is offline
Registered User
 
Join Date: Oct 2002
Location: Baghdad, Iraq
Posts: 697
It's late so I'm not going to walk through this extensively, but here's a subroutine you can add to help you with CSV files.

Code:
# Formats a single line of CSV data.
sub csv {
    my(@a) = @_; # Work on a copy of data
    $_ = defined ? $_ : '' for @a; # Deal with undefined data
    s/"/""/gx for @a; # Double up quotes, that's all you need for CSV
    join(',', map(qq/"$_"/, @a))."\n"; # Add outside quotes, commas and end of line
}
To use it:

Code:
print csv($givenname, $familyname, $address);
It doesn't care how many variables you give it. Just stick it at the top of your file. This is based on how Excel and other programs I've seen expect CSV files to look. If you have another piece of software, generate some data with troublesome characters (comma, double quotes, spaces, and newlines within a string) to attach and we can see how it handles them.
Reply With Quote
  #5 (permalink)  
Old 07-03-07, 00:41
KevinADC KevinADC is offline
Registered User
 
Join Date: Feb 2006
Posts: 56
Quote:
Originally Posted by sco08y
Looking at your code:

Code:
 #!/usr/bin/perl
The "shebang" line (because # is a sharp and ! is a bang) has to be the first line. It's optional; you can always execute your script with perl scriptname.pl. The only reason to have a shebang line is if you want your script to be executable. If you don't know what chmod +x does, don't bother with it.
Otional on windows but it doesn't hurt anything to have it there. I sure hope they come back and read all that good info you posted.
Reply With Quote
  #6 (permalink)  
Old 07-03-07, 14:15
PCheung PCheung is offline
Registered User
 
Join Date: May 2007
Posts: 2
Creating files using CSV delimiters

Thank you very much for your help it is very much appreciated. I did manage
to get my code working and since then have found it easier to use PHP and
MySQL to get the results I was after. However, I must say I do like PERL and
will be using it server side to do the real work of data processing and
thereafter pass the results back to PHP to carry on doing the fetching and
carrying.
Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

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
Trackbacks are On
Pingbacks are On
Refbacks are On