Hello,

I have a file

inputfile
abc
pqr
ghi
lmn
xyz

How do I extract certain line in using perl? For example: I want rows pqr, ghi, lmn. I want to assign line numbers and extract these rows..so for pqr, ghi and lmn I will use lines 2, 3 and 4 respectively. Any simple perl solution?

hi Perllearner007,

I would have really love to see what you have tried out atleast. But not-with-standing the code below could do what you want. Ofcourse, there are other ways of achieving this same thing. Any of the code below will do the job nicely!

#!/usr/bin/perl
use warnings;
use strict;

my $file = 'input_file.txt';    # input file
open my $fh, '<', $file or die "can't open file: $!";
while ( defined( my $line = <$fh> ) ) {
    chomp $line;
    print $line, $/ if $line =~ m/pqr/ .. $line =~ m/lmn/;
}
close $fh or die "can't close file: $!";

The above used regex to find and parse the lines using Perl list range ($start .. $end)

#!/usr/bin/perl
use warnings;
use strict;

my $file = 'input_file.txt';    # input file
open my $fh, '<', $file or die "can't open file: $!";
while ( defined( my $line = <$fh> ) ) {
    chomp $line;
    print $line, $/ if $. == 3 .. $. == 5;    # use $INPUT_LINE_NUMBER $.
}
close $fh or die "can't close file: $!";

The second solution used the same way but now used Perl $INPUT_LINE_NUMBER $. to find and print and since we have the fore knownlegde of the line number.

#!/usr/bin/perl
use warnings;
use strict;
use Tie::File;

my $file = 'input_file.txt';    # input file
tie my @input_file, 'Tie::File', $file or die "can't tie file:$!";

print join "\n", @input_file[ 2 .. 4 ];    # array index start from 0 not 1.

untie @input_file;

This instead use a perl core module Tie::File to get the whole file into an array and then print using the array index.

#!/usr/bin/perl
use warnings;
use strict;

print map { $_ if /pqr/ .. /lmn/ } grep { $_ } <>;

You will run this script adove like so:
perl_script.pl input_file.txt

You may really want to play around with map and grep in perl!

Hope this helps.

Edited 4 Years Ago by 2teez

Thanks 2teez for such a quick input. I realised my question is a bit confusing. Your script works great though I am not parsing a range ..Why I mentioned row(line) number was because I want specific line numbers (which are actually the rows in the input files). So for example I need to parse lets say, an example/dummy file

input name  value
abc        1.2
pqr        3.4
lmn        4.5
srt        6.5
uvw        7.5
xyz        4.4

I need pqr..then lmn then the other row can be uvw. So it's is not necessarily a range. I used this for when I need a specific word..which gives me the whole row.

#! /usr/local/bin/perl

open (file, "/Users/myfolder"); 
#open a new file which has to be made
open (my $out, ">outputfile.txt");


while ($line = <file>) {
        if ($line =~ m/lmn/) {

                printf ("$line");
        }
}
close (file);

Which gave me

lmn 4.5

But now I have many rows.

Hi Perllearner007,
Nice one!
ofcourse, any of the codes I gave could do what you wanted. However, you will need to know either the start and end string you want to find or their line numbers.
So, if we take the line number solution, in other words you know the line of numbers of all the lines you are looking for. Let modify one of the code above.

#!/usr/bin/perl
use warnings;
use strict;

my $file = 'input_file.txt';    # input file

#ask user for the line numbers they will need
print "Please Enter the line Number to Start from: ";
chomp( my $start_from = <STDIN> );

print "Please Enter the line Number to Stop: ";
chomp( my $to_stop = <STDIN> );

open my $fh, '<', $file or die "can't open file: $!";
while ( defined( my $line = <$fh> ) ) {
    chomp $line;
    print $line, $/
      if $. == $start_from .. $. == $to_stop;    # use $INPUT_LINE_NUMBER $.
}
close $fh or die "can't close file: $!";

Then the solution becomes interractive and simple.
By the way you will have to check if the user enter line number that doesn't exists or other user error that may occur! Ofcourse, that is easy to fix!
Hope this helps

Edited 4 Years Ago by 2teez

Hi Perllearner007,

Since you said

I used this for when I need a specific word..which gives me the whole row.
But now I have many rows

Range is taken out of the way now.
Then we can say hash is up to the task! The code below solve the problem.

#!/usr/bin/perl
use warnings;
use strict;

my $file = 'input_file.txt';    # input file

my %sorted_input;
open my $fh, '<', $file or die "can't open file: $!";
my $heading = <$fh>;            ## get the heading
while ( defined( my $line = <$fh> ) ) {
    chomp $line;
    my ($rec) = split /\s+/, $line, 2;
    $sorted_input{$rec} = $line;
}
close $fh or die "can't close file: $!";

my $get_value;
my $seek_values = [];

CHECKER: {
    do {
        print "Enter the value you seek: ";
        chomp( $get_value = <STDIN> );
        last CHECKER if $get_value eq 'q';
        if ( !exists $sorted_input{$get_value} ) {
            print "Such key does not exist, try another one\n";
            redo CHECKER;
        }
        else {
            push @{$seek_values}, $sorted_input{$get_value};
        }
    } while ( $get_value ne 'q' );
}
print $heading;
print join "\n", @{$seek_values};

Hope this helps and solve the problem!

Edited 4 Years Ago by 2teez

Hi 2teez. Both the codes work perfectly. Thanks so much for such prompt replies. Interactive scripts are fun to use:)

Glad to know you are enjoying this! Please, if this problem is solved and you are satisfied, mark this post solved. Thank you. :-)

Edited 4 Years Ago by 2teez

This question has already been answered. Start a new discussion instead.