-1

I have a file which looks like below:

LINE abc 1 somevalue
LINE abc 1 somevalue
LINE abc 1 somevalue
LINE def 2 somevalue
LINE def 2 somevalue
LINE abc 3 somevalue
LINE abc 3 somevalue
LINE mno 4 somevalue
LINE mno 4 somevalue
LINE def 5 somevalue
LINE def 5 somevalue

I would like to print the one occurrence of 'abc' or 'def' (which can be identified by column 3) etc as it is present in multiple lines. I would like to get the out put as:

LINE abc 1 somevalue
LINE abc 1 somevalue
LINE abc 1 somevalue
LINE def 2 somevalue
LINE def 2 somevalue
LINE mno 4 somevalue
LINE mno 4 somevalue

Could any one help me in perl ?

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • Not sure what you really want. Do you want the first occurrence multiple times and ignore the later ones? – Olaf Dietsche Feb 25 '13 at 16:45
  • Its a part of program that i am trying to write. I will edit and put what I have tried. @OlafDietsche Yes –  Feb 25 '13 at 16:45

2 Answers2

3

You can save the the already seen lines in a hash and skip lines which are already recognized

use strict;
use warnings;

my %seen;

while (<>) {
    my @cols = split;
    if (defined($seen{$cols[1]})) {
        if ($seen{$cols[1]} == $cols[2]) {
            print;
        }
    } else {
        $seen{$cols[1]} = $cols[2];
        print;
    }
}

This reads the lines and looks, if the second column appears already in the %seen hash. If it does, it prints the line, if the third column is the same. Otherwise it stores the line as a new one for later reference.

Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
1

I must say, the output you show does not match any reasonable interpretation that I can come up with of your problem statement "I would like to print the one occurrence of 'abc' or 'def' (which can be identified by column 3)"

#!/usr/bin/env perl

while (my $line = <DATA>) {
    my @cols = split ' ', $line;
    next if ($cols[1] =~ /\A(?:abc|def)\z/) # if col 2 is abc or def
        and $cols[2] != 1;                  # and col 3 is not 1, then skip
    print $line;                            # otherwise print
}

__DATA__
LINE abc 1 somevalue
LINE abc 1 somevalue
LINE abc 1 somevalue
LINE def 2 somevalue
LINE def 2 somevalue
LINE abc 3 somevalue
LINE abc 3 somevalue
LINE mno 4 somevalue
LINE mno 4 somevalue
LINE def 5 somevalue
LINE def 5 somevalue

Or, if you want it on the command-line,

$ perl -ane '$F[1] =~ /\A(?:abc|def)\z/ and $F[2] != 1 and next or print' input

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339