in reply to Deleting first and last TWO(2) lines of a text file

Something like this should work:

#!/usr/bin/perl <>; while($line = <>) { print if defined; $_ = $line; }

Explanation: the angle bracket operator reads a line from a while, so the first line is read and discarded. After that, $_ (Perl's implicit topic variable) is used to store the previous line; it's initially undefined, so the print statement doesn't get executed on the first loop iteration, only the subsequent ones. Since only the previous line gets printed, not the current line, the last line of the file is skipped.

EDIT: here's a slightly more idiomatic solution:

#!/usr/bin/perl <>; while(<>) { last if eof; print; }

It's pretty much the same as before, but does away with remembering the previous line and instead just exits the loop before printing if the end of the file has been reached, thus neglecting to print the last line.

EDIT 2: just so there's no confusion in the future, the OP originally asked for the first and last line of a text file to be removed, not the first line and last two lines.

Replies are listed 'Best First'.
Re^2: Deleting first and last lines of a text file
by vsmeruga (Acolyte) on May 16, 2014 at 09:45 UTC
    Hi Where are we specifying the filename here?. Thanks VJ

      You can either have the script read from STDIN, or supply a filename as an argument, i.e.:

      $ perl script.pl data.dat

      or

      $ cat data.dat | perl script.pl

      Such is the magic of the angle bracket operator when used with a null filehandle. Quoting perlop:

      The null filehandle <> is special: it can be used to emulate the behavior of sed and awk, and any other Unix filter program that takes a list of filenames, doing the same to each line of input from all of them. Input from <> comes either from standard input, or from each file listed on the command line. Here's how it works: the first time <> is evaluated, the @ARGV array is checked, and if it is empty, $ARGV[0] is set to "-", which when opened gives you standard input. The @ARGV array is then processed as a list of filenames. The loop

      while (<>) { ... # code for each line }

      is equivalent to the following Perl-like pseudo code:

      unshift(@ARGV, '-') unless @ARGV; while ($ARGV = shift) { open(ARGV, $ARGV); while (<ARGV>) { ... # code for each line } }

      except that it isn't so cumbersome to say, and will actually work. It really does shift the @ARGV array and put the current filename into the $ARGV variable. It also uses filehandle ARGV internally. <> is just a synonym for <ARGV>, which is magical. (The pseudo code above doesn't work because it treats <ARGV> as non-magical.)

      Hope this helps!

Re^2: Deleting first and last lines of a text file
by vsmeruga (Acolyte) on May 16, 2014 at 13:06 UTC

    Hi I tried with below code calling scripts as ./scriptname srcfile.txt. But it deleted just the first line. Not last 2 lines/1 line </p?

    #!/usr/bin/perl my $file='jjl.exec.txt'; open STDOUT, ">", $file or die "$0: open: $!"; open STDERR, ">&STDOUT" or die "$0: dup: $!"; <>; while($line = <>) { print if defined; $_ = $line; }

      Hmm, that should... and is, in fact, working for me. Are you sure there's not simply an empty line at the end of your input file? Perhaps you could share some sample data.

      Also, why the open calls? If you want the output to go to a specific file, it'd be easier to simply redirect the script's output on the command line, like so:

      $ ./scriptname srcfile.txt >jjl.exec.txt

      Alternatively, I'd suggest at least using a different filehandle than STDOUT, though you'd of course have to adjust the print statement to print to that filehandle then. opening STDOUT like that apparently works, but it's giving me the heebies.