Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

How to Print Every Other Line

by Neuroactive (Acolyte)
on Jun 30, 2004 at 17:10 UTC ( [id://370810]=perlquestion: print w/replies, xml ) Need Help??

Neuroactive has asked for the wisdom of the Perl Monks concerning the following question:

I feel a little silly asking what seems like such a simple question. But since there are a lot of Perl operators and functions I haven't yet had the chance to use (and the Perl Programming and Cookbook books I borrowed don't seem to directly discuss how to do it), I have only a couple of vague ideas.

I need to print the odd lines of one file into another, and then do a bunch of other file combining and other stuff (which I know how to do) afterward.

Any suggestions would be greatly appreciated.

Thanks!

Replies are listed 'Best First'.
Re: How to Print Every Other Line
by gaal (Parson) on Jun 30, 2004 at 17:20 UTC
    The $. variable holds the current line number. So
    while (<ONEFILE>) { print ANOTHER if $. % 2; }

    Should do the trick.
Re: How to Print Every Other Line
by davido (Cardinal) on Jun 30, 2004 at 17:33 UTC

    Some explanation of the proposed solutions is in order.

    The special variable $. contains a count of the number of lines read from the most recently read filehandle. This number starts with 1. So reading a file line by line, $. will be set to 1, 2, 3, and so on for each respective line read. Read perlvar for details.

    This is a convenience, though in this simple case, it's almost as easy to set your own iterator up ahead of time and autoincrement it prior to processing each line read.

    The next step is determining even and oddness of a number. One of the easiest ways is to find out the remainder when you divide a number by two. The "remainder" is the modulus of X / 2. And the modulus function is named %. So $x % 2 will be zero for even numbers, and some value for odd numbers. See perlop for more info.

    So if you put the two pieces together, and check $. % 2 for value, if it contains any value other than zero, you're looking at an odd line number, and should print that line.

    Another solution is to just treat the filehandle as a queue. Instead of shifting one item per loop iteration, shift two, and discard the second, and print the first each time.


    Dave

      "The "remainder" is the modulus of X / 2. And the modulus function is named %. So $x % 2 will be zero for even numbers, and some value for odd numbers."

      Some value should be one, right? (well, anyway, non-zero is true, so I'm nitpicking.)
Re: How to Print Every Other Line
by Zaxo (Archbishop) on Jun 30, 2004 at 17:24 UTC

    After you've opened *IN from the input file and *OUT to the output, use the $. variable to tell you how many lines have been read.

    while (<IN>) { print OUT $_ if 1 & $. ; }
    which will print odd-numbered lines to OUT. Replace if with unless to print even lines.

    Update: Corrected typo.

    After Compline,
    Zaxo

      Replace if with unless to print even lines.

      Or "1 & $." with "0 & $.". Or with "1 ^ $." Or ...

      --
      tbone1, YAPS (Yet Another Perl Schlub)
      And remember, if he succeeds, so what.
      - Chick McGee

        Not entirely sure "0 & $." will do anything, and "$. ^ 1" will print everything but line 1. These probably aren't the desired results.
Re: How to Print Every Other Line
by etcshadow (Priest) on Jun 30, 2004 at 17:20 UTC
    perl -ne 'print if (++$x)%2' file1 > file2
    ------------ :Wq Not an editor command: Wq
Re: How to Print Every Other Line
by gsiems (Deacon) on Jun 30, 2004 at 17:20 UTC
    How about something like:
    while (<DATA>) { print $_; <DATA> } __DATA__ 01 02 03 04 05 06 07 08 09 10 11 12
      (ahem) The original poster only wants the odd lines (1, 3, 5 etc) printed, lol.

      Update: instead of saying 'you should read better', I should read better. I'm sorry.
        ...and that's what (s)he gave. By calling the <DATA> in the loop, (s)he is taking a line and throwing it away. So, in essence, you're reading two lines and printing one.

        thor

Re: How to Print Every Other Line
by BUU (Prior) on Jun 30, 2004 at 17:20 UTC
Re: How to Print Every Other Line
by BrowserUk (Patriarch) on Jun 30, 2004 at 17:29 UTC

    Just discard every second line.

    perl -pe"<ARGV> unless eof ARGV" infile > outfile

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
Re: How to Print Every Other Line
by runrig (Abbot) on Jun 30, 2004 at 19:22 UTC
    awkmonks to the rescue!
    awk 'NR % 2' filename
    Or save the output of 'echo NR%2 | a2p' (works on DOS or Unix) and run as a perl program.
Re: How to Print Every Other Line
by orderthruchaos (Scribe) on Jun 30, 2004 at 20:53 UTC
    You can combine the above suggestions to get this cute lil' one liner:
    perl -ne 'print if $.%2' infile > outfile
Re: How to Print Every Other Line
by sgifford (Prior) on Jun 30, 2004 at 20:32 UTC
    Since you already have your answer, this is a great question for golfing! How about:
    perl -pe'eof||<>'

    Update: Fixed bug found by BrowserUK. Thanks japhy!

    Update: A few people have asked to see the original, buggy version. It was simply perl -pe'<>'.

      This fixes the problem stated with your code: perl -pe'eof||<>'
      _____________________________________________________
      Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a job (NYC-area)
      s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

      Work great for files containing an even numbers of lines, but hangs waiting for more input if the file has an odd number.


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail
      "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
      perl -pe '<>' < input
      I didn't see the original one that hung on odd numbers of lines in input (but I guess it looked like this), but on my machine this one doesn't hang. ?

      Ah, I see, it hangs if I input from STDIN, instead of a file. Have to ^D twice, anyway. Still, since the OP asked for file manipulation, I'd say this was OK for a solution..:wq

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://370810]
Approved by NovMonk
Front-paged by grinder
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (8)
As of 2024-03-28 12:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found