いくつかのテキスト ファイルを処理し、それぞれの最後の行を検出して、その時点でいくつかの操作を実行したいと考えています。この単純化された例では、ファイル名、合計行数、および奇数行を出力します。次のファイルの内容を想定しています。
==> file1 <==
one
two
three
==> file2 <==
monday
tuesday
wednesday
thursday
==> file3 <==
red
green
blue
これは私がそれを実装する方法です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;
}
}
慣れていない方のために説明すると、<>
は に似てfileinput.input()
おりARGV
、行番号カウンターをリセットするために明示的に閉じるファイルハンドルです ( $.
)。わかりやすいと思います。肝心な部分は のチェックですeof
。
しかし、これは私がそれをやろうとする方法です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()
次のように実行します。
python3 script.py file[123]
どちらのスクリプトでも同じ結果が得られます。
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
それは私が望むことをしますが、私が望む方法ではありません。のどれもStopIteration
、EOFError
または空行のチェックは最後の行を検出しません。また、追加の変数を使用しfileinput.filelineno()
て前のファイルの後処理を行うことは、少なくともperl
. 私は何か見落としてますか?この種の問題をより良い方法でどのように解決しますか?