I want to process some text files and detect last line of each one to do some operations at that point. In this simplified example, print file name, number of total lines and the odd ones. Assuming following content of files:
==> file1 <==
one
two
three
==> file2 <==
monday
tuesday
wednesday
thursday
==> file3 <==
red
green
blue
This is how I would implement it in perl
:
#!/usr/bin/env perl
use strict;
use warnings;
my (@odd);
while ( <> ) {
print $_;
if ( $. & 1 ) {
chomp;
push @odd, $_;
}
if ( eof ) {
print $ARGV, ' -- ', $., "\n";
print 'Odd lines => ', join( ':', @odd ), "\n";
undef @odd;
close ARGV;
}
}
For those who are not used to it, <>
is similar to fileinput.input()
and ARGV
is the filehandle that I close explicitly to reset the line number counter ($.
). I hope it's easy to understand. The key part is the check of eof
.
But this is how I try to do it with python
:
#!/usr/bin/env python3
from fileinput import *
fname = ''
lnumber = 0
odd = []
try:
for line in input():
if filelineno() == 1 and fname:
print('{0} -- {1}'.format(fname, lnumber))
print('Odd lines => {0}'.format(':'.join(odd)))
odd = []
fname = ''
lnumber = 0
lnumber += 1
print('{0}'.format(line), end='')
if lnumber & 1:
odd.append(line.rstrip())
if not fname:
fname = filename()
if not line:
print('Is this end of line??')
except OSError as e:
print('Operation failed: {0}'.format(e.strerror))
except EOFError as e:
print('EOF found: {0}'.format(e.strerror))
except StopIteration:
print('StopIteration reached')
finally:
print('{0} -- {1}'.format(fname, lnumber))
print('Odd lines => {0}'.format(':'.join(odd)))
close()
Running it like:
python3 script.py file[123]
Both scripts yield same result:
one
two
three
file1 -- 3
Odd lines => one:three
monday
tuesday
wednesday
thursday
file2 -- 4
Odd lines => monday:wednesday
red
green
blue
file3 -- 3
Odd lines => red:blue
It does what I want but not the way I want. None of StopIteration
, EOFError
or a check on an empty line detect last one. And the use of additional variables and fileinput.filelineno()
to do post-processing of previous file seems weird for me, at least compared with perl
. Did I miss something? How would you solve this kind of problem in a better way?