1

I have a source text in a file and looking for a code that would take the second (or n-th - in general) row from this file and print to a seperate file.

Any idea how to do this?

Ether
  • 53,118
  • 13
  • 86
  • 159
Marcin
  • 11
  • 2

5 Answers5

5

You can do this natively in Perl with the flip-flop operator and the special variable $. (used internally by ..), which contains the current line number:

# prints lines 3 to 8 inclusive from stdin:
while (<>)
{
    print if 3 .. 8;
}

Or from the command line:

perl -wne'print if 3 .. 8' < filename.txt >> output.txt

You can also do this without Perl with: head -n3 filename.txt | tail -n1 >> output.txt

Ether
  • 53,118
  • 13
  • 86
  • 159
  • so if you wanted just the second line, you could replace the line with the flip-flop operator with: print if 2 .. 2 or print if ($. == 2) yeah? – coffeepac Jul 29 '10 at 22:05
0

You could always:

  1. Read all of the file in and but it into one variable.
  2. Split the variable at the newline and store in an array
  3. Write the value at the index 1 (for the second row) or the n-1 position to the separate file
Kyra
  • 5,129
  • 5
  • 35
  • 55
0

use like this script.pl > outfile (or >> outfile for append)

this uses lexical filehandles and 3 arg open which are preferred to global filehandles and 2 arg open.

#!/usr/bin/perl
use strict;
use warnings;
use English qw( -no_match_vars );
use Carp qw( croak );

my ( $fn, $line_num ) = @ARGV;

open ( my $in_fh, '<', "$fn" ) or croak "Can't open '$fn': $OS_ERROR";

while ( my $line  = <$in_fh> ) {
    if ( $INPUT_LINE_NUMBER == $line_num ) {
        print "$line";
    }
}

note: $INPUT_LINE_NUMBER == $.

here's a slightly improved version that handles arbitrary amounts of line numbers and prints to a file.

script.pl <infile> <outfile> <num1> <num2> <num3> ...

#!/usr/bin/perl
use strict;
use warnings;
use English qw( -no_match_vars );
use Carp qw( croak );
use List::MoreUtils qw( any );

my ( $ifn, $ofn, @line_nums ) = @ARGV;

open ( my $in_fh , '<', "$ifn" ) or croak "can't open '$ifn': $OS_ERROR";
open ( my $out_fh, '>', "$ofn" ) or croak "can't open '$ofn': $OS_ERROR";

while ( my $line  = <$in_fh> ) {
    if ( any { $INPUT_LINE_NUMBER eq $_ } @line_nums ) {
        print { $out_fh } "$line";
    }
}
xenoterracide
  • 16,274
  • 24
  • 118
  • 243
  • Don't write `"$fn"` for `$fn`. – tchrist Nov 01 '10 at 18:07
  • Because it’s a no-op unless you have an object with overloaded `q("")` operator or it’s a non-blessed or at least non-overloaded reference which you wish to otherwise kill through stringification into something like `HASH(0x8039e0)`. It just confuses matters. If you want the string contained in `$fn`, just say `$fn`. – tchrist Nov 03 '10 at 13:48
-1

I think this will do what you want:

line_transfer_script.pl:

open(READFILE, "<file_to_read_from.txt");
open(WRITEFILE, ">File_to_write_to.txt");

my $line_to_print = $ARGV[0]; // you can set this to whatever you want, just pass the line you want transferred in as the first argument to the script
my $current_line_counter = 0;

while( my $current_line = <READFILE> ) {
  if( $current_line_counter == $line_to_print ) {
     print WRITEFILE $current_line;
  }

  $current_line_counter++;
}

close(WRITEFILE);
close(READFILE);

Then you'd call it like: perl line_transfer_script.pl 2 and that would write the 2nd line from file_to_read_from.txt into file_to_write_to.txt.

coffeepac
  • 634
  • 5
  • 13
-1
my $content = `tail -n +$line $input`;

open OUTPUT, ">$output" or die $!;
print OUTPUT $content;
close OUTPUT;
Vincent Robert
  • 35,564
  • 14
  • 82
  • 119