[lug] Output every xth line?

Jeffery D. Collins jcollins at boulder.net
Sat Nov 22 14:29:41 MST 2003


The Matt wrote:

>Folks, I need your Unix knowledge.  I have an input file that contains
>data that isn't marked nice enough that I can use grep to parse it.
>
>Rather, I find I need a script that says "starting with line x, output
>that line and every yth line after it".  That is, start at line 5 and
>output line 5, 5+y, 5+2y, &c.  Can you think of a quick shell script
>that can do this?  My attempts have been rather laughable mainly because
>I am neither a perl hacker or a shell script hacker.  (I could make one
>in Fortran 95, but it wouldn't be very portable.)
>
>Any help for the poor grad student?
>
>Matt
>  
>
I've had a need for something similar to this in the past and decided to 
try out the more recent features of python.

#
# usage: lines.py <start> <incr> <file>
#
import sys
file = sys.argv[-1]
start, incr = [int(arg) for arg in sys.argv[1:-1]]

# The following are 3 different ways to solve the problem, trading
# memory and speed in various proportions.

# implementation 1
print
print "read the entire file and slice it"
fh = open(file)
sys.stdout.writelines( fh.readlines()[start:-1:incr])
fh.close()

# implementation 2
print
print 'list comprehensions temporarily store the output but not the input'
fh = open(file)
sys.stdout.writelines([l for (c, l) in enumerate(fh) if c >= start and 
(c-start) % incr == 0])
fh.close()

# implementation 3
print
print "using generators to avoid temporary input and output storage"
def linefilter(fh, start, incr):
    for count, line in enumerate(fh):
        if (count - start) % incr == 0 and count >= start:
            yield line
fh = open(file)
sys.stdout.writelines(linefilter(fh, start, incr))
fh.close()


-- 
Jeffery Collins (http://www.boulder.net/~jcollins)





More information about the LUG mailing list