0

多数のログファイルをループしようとしていますが、ループしているすべてのファイルでファイルエントリ(行)を並べ替える必要があります

これは私がしていることです:

import glob

f = glob.glob('logs/')
for line in sorted(fileinput.input(f), key=stringsplit(line)):
  print line

したがって、すべてのファイルを開いてから、stringsplit関数(ファイルエントリから日付を抽出する)を並べ替え基準として使用したいと思います。

問題は、これを行うと次のようなエラーが発生することです。

name 'line' is not defined

質問:ループされているパラメータをソート関数
に渡すことはできませんか?lineこれはどのように行うことができますか?

ありがとう!

4

2 に答える 2

2

試してみてくださいkey=lambda line: stringsplit(line)

ソートは、forループでの反復を開始する前に行われます。

于 2013-03-08T15:43:54.617 に答える
1

キーワードはkey呼び出し可能でなければなりません。入力シーケンスのすべてのエントリに対して呼び出されます。

Alambdaは、そのような呼び出し可能オブジェクトを作成する簡単な方法です。

sorted(..., key=lambda line: stringsplit(line))

ただし、多くの大きなファイルでの出力をソートすることには非常に注意が必要です。それらをソートできるようにするには、すべての行をメモリに読み込む必要があります。ファイルが多いか大きい場合、すべてのメモリを使い果たし、最終的に例外が発生します。fileinputsorted() MemoryError

別の方法を使用して、最初にログを事前に並べ替えます。UNIXツールsortを使用するか、代わりに外部の並べ替え手法を使用できます。

入力ファイルがすでにソートされている場合は、同じキーを使用してそれらをマージできます。

import operator

def mergeiter(*iterables, **kwargs):
    """Given a set of sorted iterables, yield the next value in merged order"""
    iterables = [iter(it) for it in iterables]
    iterables = {i: [next(it), i, it] for i, it in enumerate(iterables)}
    if 'key' not in kwargs:
        key = operator.itemgetter(0)
    else:
        key = lambda item, key=kwargs['key']: key(item[0])

    while True:
        value, i, it = min(iterables.values(), key=key)
        yield value
        try:
            iterables[i][0] = next(it)
        except StopIteration:
            del iterables[i]
            if not iterables:
                raise

次に、開いているファイルオブジェクトを渡します。

files = [open(f) for f in glob.glob('logs/*')]
for line in mergeiter(*files, key=lambda line: stringsplit(line)):
    # lines are looped over in merged order.

ただし、関数が入力ログファイルで順序付けられた値を返すことを確認する必要があります。stringsplit()

于 2013-03-08T15:43:07.470 に答える