#!/usr/bin/perl use strict; use warnings; my @records; my %max; while (<DATA>) { my @fields = split; my ( $number, $name ) = ( $fields[3] =~ /^(\d+),(\w+)/ ); if ( ! $number or ! $name ) { warn "Line $.: unexpected input ignored: $_"; next; } $max{$name} = $number unless ( exists( $max{$name} ) and $max{$name} >= $number ); push @records, { name => $name, data => $_ }; } for my $rec ( @records ) { my $name = $rec->{name}; my $max = $max{$name}; my $flag = ( $max == 1 ) ? 'single' : 'end'; $rec->{data} =~ s/(\s)$max,$name,/$1$flag,$name,/; print $rec->{data}; } __DATA__ 62556 63635 y 1,andrew,JJ113954 63868 63897 h 1,morgan,JJ113955 68766 69005 j 2,morgan,JJ113955 81099 81630 y 1,flintoff,JJ113952 126185 126699 s 1,austin,JJ113956 135356 135449 3 1,peter,JJ113952 135588 136297 8 2,peter,JJ113952 158146 158367 i 3,peter,JJ113952 441474 441538 b 9,catherine,JJ029490 442666 442843 9 8,catherine,JJ029490 445778 445905 0 7,catherine,JJ029490 446059 446273 l 6,catherine,JJ029490 450319 450379 f 5,catherine,JJ029490
(updated to add a condition for skipping lines that don't match /\d+,\w+/ in fourth field-- it pays to be careful...)
In the for loop, the $rec->{data} =~ s/.../.../ will do nothing on the lines that don't contain the max value for a given name, because the regex won't match. For lines that contain a max value, the replacement will be either "single" or "end" depending on what the max value is.
In order to read from a file name that you put on the command line (i.e. in @ARGV) when you run the script, just remove DATA from while(<DATA>) (and leave off the __DATA__ section at the end) -- there's no need to explicitly open a file whose name is provided via @ARGV.
In reply to Re: Tagging the last elements
by graff
in thread Tagging the last elements
by crochunter
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |