William Martell wrote:
>
> Hello All,
Hello,
> Thanks for reading my email. I am trying to read a fix length text file and
> extract specific substrings from each line. I would like to extract
> specific things depending on which line is being read so I can avoid picking
> up trash reading every line. The pattern repeats itself over and over again
> until completion, so I think I should set a counter and then use the counter
> to choose which set to extract, then I will reset the counter again to
> repeat the process. I am having trouble understanding how to set the
> counter and determine what line is being read to extract.
>
> Any help or hints would be greatly appreciated.
>
> Here is my code.-------------------------------------------#!/perl
>
> open (INFILE, "artb30_short.da4") || die "Can't open artb30.da4 file.";
You should include the $! variable in the error message so that you know why it failed.
> my @order_detail;
>
> @data = <INFILE>;
>
> foreach $row ( @data ){
>From your code it doesn't look like you need to slurp the entire file into memory.
while ( <INFILE> ) {
> if( $row == 1 ){
$row contains the contents of the current line, not the line number
> # extract fields for row 1
> my %item1 = (
> cust_number => substr( $line, 0, 6 ),
> cust_name => substr( $line, 8, 31 ),
> cycle => substr( $line, 40, 5 ),
> customer_type => substr( $line, 47, 15 ),
> acct_contact => substr( $line, 64, 20 ),
> phone => substr( $line, 86, 15 ),
> credit_limit => substr( $line, 104 )
> );
>
> # trim spaces
> while ( my ($key, $value) = each %item1 ) {
> $value =~ s/^\s+//; #beginning spaces
> $value =~ s/\s+$//; #ending spaces
> }
You can simplify that by using values():
for ( values %item1 ) {
s/^\s+//; #beginning spaces
s/\s+$//; #ending spaces
}
Or just the hash itself:
for ( %item1 ) {
s/^\s+//; #beginning spaces
s/\s+$//; #ending spaces
}
> # save for later processing
> push @order_detail, \%item1;
>
> [snip code]
Here is one way to do it:
my $file = 'artb30_short.da4';
open INFILE, $file or die "Can't open $file: $!";
my @order_detail;
while ( <INFILE> ) {
last if /^GROUP TOTALS/;
s/\s+\Z//; # remove all trailing whitespace
next unless /\d\.\d\d\Z/; # only want lines with dollar amounts at end
my %item;
if ( length() < 120 ) { # item 1 lines are shorter
@item{ qw/cust_number cust_name cycle customer_type acct_contact phone
credit_limit/ } =
map { s/^\s+//; $_ }
unpack 'A6 x2 A30 x2 A5 x2 A15 x2 A20 x2 A15 x2 A*', $_;
# unpack'A' removes trailing whitespace so we need the map{}
# to remove leading whitespace
}
elsif ( /^\d/ ) { # item 2 lines start with a digit
@item{ qw/inv_no type inv_date current days_1_30 days_31_60
days_61_90 days_over_90 on_hold unap_cash total_ar/ } =
map { s/^\s+//; $_ }
unpack 'A6 x A3 x A8' . 'x3 A11' x 8, $_;
}
else { # item 3 lines
@item{ qw/cust_totals_current cust_totals_days_1_30 cust_totals_days_31_60
cust_totals_days_61_90 cust_totals_days_over_90 cust_totals_on_hold
cust_totals_unap_cash cust_totals_total_ar/ } =
map { s/^\s+//; $_ }
unpack 'x19' . 'x3 A11' x 8, $_;
}
push @order_detail, \%item;
}
John
--
use Perl;
program
fulfillment
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>