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 TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Extract 5 bytes at a time 1

Status
Not open for further replies.

dshaw21369

Programmer
Jul 8, 2002
64
I' m fairly new to Perl, and what Im trying to do is :

1. Loop through each line of an array
2. Extract five bytes at a time
3. Store
4. add a space b/w five byte

each line contains:
30130301313G11341669416864168741783418664509A
want to accomplish:
30130 30131 3G113 41669 41686 41687 41783 41866 4509A
 

Code:
# 1.  Loop through each line (element) in array:

foreach $element (@array){

# 2.  "extract 5 bytes at a time." 

  while($element =~ /.{5}/g){
  
    # 3.  Store?  Ummm...
    push @chunks, $&;

  }

  # 4.  Add space b/w chunks.
  $new_line = "@chunks";
  print $new_line, "\n";
  @chunks = ();

}
This is untested, but hopefully will do what you want.

--jim

 
Wow I would of never figured that one out!!!
what does push mean???
Thanks so much for your help!
 
How do I use @chunks globally so I can use this value in another place in my program?????


foreach $cobol_out_sections (@all_sections_CES)

{


while($cobol_out_sections =~ /.{5}/g)

{

push @chunks, $&;

}

$new_line = "@chunks";
@chunks2=(@chunks2,@chunks);
@chunks = ();

}



print Debug "@chunks2 \n";
 
Getting more advanced: the 2D array! I figure that giving
a array of strings is probably good enough, but an Array of Array's is more flexible in the long run. Plus, if you don't already know how to implement them, this is a good opportunity.
Code:
my @AoA;  # declared outside of block

foreach $cobol_out_sections (@all_sections_CES){

  while($cobol_out_sections =~ /.{5}/g){
      push @chunks, $&;
  }
  
  push @AoA, [ @chunks ]; # the [] denote anonymous array
                          # reference.  
  @chunks = ();

}

# now lets look at that data structure:

print $AoA[0][0], "\n";  # displays the first chunk of the 
                   # first line

print $AoA[0][4], "\n";  # first line, 5th chunk

print $AoA[3][-1], "\n"; # fourth line, LAST chunk

# This is great if you know which element you want,
# but what about iterating through each element of each
# array?

foreach $anonymous_array_reference ( @AoA ){
  # At this point, our iteration variable is a reference
  # to an anonymous array, you can treat it like a 
  # normal array by dereferencing it with the:
  # @{ $ARRAY_REF_GOES_HERE }
  
  foreach $element ( @{ $anonymous_array_reference } ){
    
    print $element, " ";
  
  }
  print "\n";
}

Hope this helps.

--jim
 
Hey Jim,
Thanks for taking the time to explain 2D Array! and yes it does help!!!
 
While the following snippet of Jim's code is perfectly correct:

while($cobol_out_sections =~ /.{5}/g)
{
push @chunks, $&;
}

I would like to point out something that many are unaware of. The regular expression variable $& matches the current pattern, along with $` and $' matching the portion of the string before and after the matched pattern respectively.

If you have a rather large script, which has many regular expressions, but only one or two use the $& (or $` or $') internal variables, Perl will do some extra behind the scenes work to ensure that every regular expression stores values in the 3 variables for every single regular expression match. As you can imagine this can be a considerable overhead if your script is continually copying large strings internally, into variables that will never be used.

A better way to write the above code to illiminate this overhead is:

while($cobol_out_sections =~ /(.{5})/g)
{
push @chunks, $1;
}

The $1, $2 ... internal variables are only updated on a captured match, so there is no overhead.

I recently saw a talk by Nick Clark, of London.pm, which highlighted this problem.
Barbie
Leader of Birmingham Perl Mongers
 
True. However, while that is perfectly correct, using an intermediate variable is ultimately inneficient period. A better way to eliminate THIS overhead is:

@chunks = $cobol_out_sections =~ /.{5}/g;

And just forget about the inner loop. But that's a little hard to understand for a beginner. Simplicity sometimes is more appropriate than efficiency.

--jim
 
how can I print this????

I'm Looking for output like this:

AL10 0003 31811 31814 3G199

but getting this:

31811 31814 3G199
AL10
0003


Here is my code:

%cobol_out_seen = ();
@uniq_cobol_out = ();


#### Get only Unique lines

foreach $cobol_out_item (@cobol_out_message)
{
unless ($cobol_out_seen{$cobol_out_item})
{
$cobol_out_seen{$cobol_out_item} = 1;
push(@uniq_cobol_out, $cobol_out_item);

}
}


### Get Circ ID, Get Section count, Get all sections

foreach $cobol_out_record(@uniq_cobol_out)

{
$cobol_out_snapshot= substr($cobol_out_record,46,6);
if ($cobol_out_snapshot eq "SSSSSE")

{
@yesterdays_cobol_out_message = $cobol_out_record;
@cobol_out_circ_id= substr($cobol_out_record,93,5);
@cobol_out_circ_id_2=(@cobol_out_circ_id_2,@cobol_out_circ_id);
@section_count=substr($cobol_out_record,98,4);
@section_count2=(@section_count2,@section_count);
@all_sections=substr($cobol_out_record,102,100);
@all_sections_CES=(@all_sections_CES,@all_sections);


}



}



#### Loop through Sections Extract 5 at a time and add space b/w


foreach $cobol_out_sections (@all_sections_CES)

{


while($cobol_out_sections =~ /.{5}/g)

{

push @chunks, $&;

}

$new_line = "@chunks";
print Snapshot "$new_line \n";
@chunks = ();

}


############################################### PRINT STATEMENTS #########################################################



foreach $circuit (@cobol_out_circ_id_2)

{
print Snapshot "$circuit \n";
}



foreach $section_count (@section_count2)

{
print Snapshot "$section_count \n";
}




 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top