Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Re^2: Removing specific array elements

by phamalda (Novice)
on Feb 01, 2016 at 12:49 UTC ( #1154181=note: print w/replies, xml ) Need Help??

in reply to Re: Removing specific array elements
in thread Removing specific array elements

Thank you all for the quick replies. I apologize for the ambiguity in the first post and for the delayed response. Below is my entire piece of code:

#!/usr/bin/perl -w use strict; # Enforce good programming rules use warnings; # Provides run-time warnings my $infile; # Variable for input file my $outfile; # Variable for output file my $filetype; # Variable to store whether the file is Standard or E +nhanced my @newlines; # Array variable to hold line in incoming text file variable. if (not defined $ARGV[0]) { die "Usage: <inputfile>\n"; } else { $infile = $ARGV[0]; } open(INFILE, $infile) || die "$infile not found in current location.\n +"; chomp(my @lines = <INFILE>); close(INFILE); # Place header from source file into $header variable my $header = $lines[0]; my @field = split("~", $lines[1]); if ($field[14]) { $filetype = 'Enhanced'; } else { $filetype = 'Standard'; } push (@newlines, $header); if ($filetype eq 'Enhanced') { # Loop through each index in the @lines array. foreach my $line (@lines) { my @field = split("~", $line); if ($field[11] eq '000015') { $line =~ s/$field[12]/92/g; $line =~ s/~~~~~~~~~10~/~10~/g; push(@newlines,$line); } if ($field[11] eq '000030') { $line =~ s/$field[12]/46/g; $line =~ s/~~~~~10~/~10~/g; push(@newlines,$line); } if ($field[11] eq '000060') { $line =~ s/$field[12]/23/g; $line =~ s/~~~10~/~10~/g; push(@newlines,$line); } } # End foreach } # End if if (defined $ARGV[1]) { $outfile = $ARGV[1]; } else { $outfile = "resultfile.txt"; } open my $fh, '>', $outfile or die "Cannot opent $outfile\n"; foreach (@newlines) { print $fh "$_\n"; } close $fh;

And I have included two lines from the file this is altering:

MEPMD01~20080519~03092015124400AM~6202820945~PPAY RES~~0012435644-01~OK~E~KWH~~000015~96~03082015121500AM~00~0.288~00~0.2892~00~0.2778~00~0.2484~00~0.4356~00~0.3882~00~0.0702~00~0.2988~~~~~~~~~10~0.279~10~0.2796~10~0.2964~10~0.2718~10~0.2082~10~0.1242~10~0.2568~10~0.258~10~0.2958~10~0.2772~10~0.276~10~0.2928~10~0.2904~10~0.2814~10~0.2556~10~0.276~10~0.0924~10~0.4878~10~0.3366~10~0.2814~10~0.273~10~0.2778~10~0.2862~10~0.2766~10~0.288~10~0.0402~10~0.4326~10~0.2976~10~0.0366~10~0.0318~10~0.0486~10~0.3084~10~0.048~10~0.03~10~0.0246~10~0.0402~10~0.0204~10~0.0204~10~0.051~10~0.0246~10~0.0306~10~0.0342~10~0.0306~10~0.0258~10~0.0402~10~0.0384~10~0.0342~10~0.021~10~0.021~10~0.0366~10~0.0204~10~0.0312~10~0.0372~10~0.0204~10~0.0282~10~0.0432~10~0.021~10~0.0216~10~0.048~10~0.0234~10~0.0192~10~0.0372~10~0.0192~10~0.018~10~0.0474~10~0.0414~10~0.0768~10~0.0588~10~0.0558~10~0.0594~10~0.0702~10~0.1446~10~0.1068~10~0.1548~10~0.1704~10~0.0684~10~0.0936~10~0.0834~10~0.1134~10~0.0666~10~0.039~10~0.048~10~0.0414~10~0.015~


My split creates an array for each string with a tilde delimiter. You can see each both line, there is a string of tildes '~~~~~~~~~' but they are at different character count in each line. Another problem is that in rare cases, this string of tildes might appear later in the line and I cannot remove it if it does.

One direction I had was to put each line array in a while loop inside that foreach and count through each element of the array and move it to the farthest null element to the left but the nested loop creates a lot of overhead for each line of text.

I hope this clears up some of the details. Again, any help would be greatly appreciated.


Replies are listed 'Best First'.
Re^3: Removing specific array elements
by poj (Abbot) on Feb 01, 2016 at 14:29 UTC

    If I have read correctly you are scanning an input file and outputting changed lines only where column 12 is 000015, 000030 or 000060. Column 13 is changed to 92, 46 or 23 and a number of blank columns (8, 4 or 2) starting at 30 are removed.

    Since there looks to be a pattern to your changes I have coded them into a hash to avoid the multiple ifs.

    #!/usr/bin/perl use strict; use warnings; my $infile = $ARGV[0]; my $outfile = $ARGV[1] || 'resultfile.txt'; unless (@ARGV) { die "Usage: <inputfile> [<outputfile>] \n"; } open IN, '<', $infile or die "$infile not found in current location"; open OUT, '>', $outfile or die "Cannot open $outfile"; # Place header from source file into $header variable my $header = <IN>; print OUT $header; # changes my %change = ( '000015' => [92,30,8], '000030' => [46,30,4], '000060' => [23,30,2], ); # enhanced or standard files my @field = split "~",<IN>;; my $filetype = $field[14] ? 'Enhanced' : 'Standard'; if ($filetype eq 'Enhanced') { # process lines my $count=0; foreach my $line (<IN>) { ++$count; chomp($line); my @field = split "~", $line; if ( exists $change{$field[11]} ) { $field[12] = $change{$field[11]}[0]; my $posn = $change{$field[11]}[1]; my $cut = $change{$field[11]}[2]; my $discard = join '',splice(@field,$posn,$cut); warn "Warn : $discard discarded at line $count" if ($discard); print OUT join '~',@field; print OUT "\n"; } } print "$count lines processed from $infile\n"; } close IN; close OUT;

    Note the first 2 lines of input are not processed



      It took me a minute to see how the use of the array inside the hash actually worked but this is brilliant! Thank you again for your assist on this. This is precisely where I needed to be.



      This is perfect. I hadn't investigating using a hash in this code. Thank you so much.


Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1154181]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (3)
As of 2022-01-19 19:01 GMT
Find Nodes?
    Voting Booth?
    In 2022, my preferred method to securely store passwords is:

    Results (55 votes). Check out past polls.