3

かなり大きなファイルのセット (それぞれ約 50 メガバイト、少なくとも 100 個のファイル) がありますが、処理のために各ファイルに小さなヘッダー (約 20 行) を挿入する必要があります。それを行うために bash または python でスクリプトを書きたいと思っていましたが、テキスト ファイルの先頭に挿入できる定数時間関数が見つかりません。一定時間じゃないと完成まで時間がかかりすぎると思います。誰もこの問題の経験がありますか?

4

3 に答える 3

3

テキストを Unix ファイルに一定時間内に挿入することはできません。最初でも途中でもありません。一方で、意図する処理によっては、挿入を完全に回避できる可能性がわずかにあります。処理ツールがパイプから読み取ることができる場合に機能します。次に、次のようなことができます

cat headerfile datafile | myprocessingtool

データファイルが実際に変更されないようにします。

于 2013-05-20T14:37:47.787 に答える
2

これはあなたが行う最善の方法に近いと思います(bash):

MYHEADER=/path/to/the/header
HEADERSIZE=$(stat --format %s "$MYHEADER")

for FILENAME in $FILES; do
    OLDSIZE=$(stat --format %s "$FILENAME")
    cat "$MYHEADER" "$FILENAME" > /tmp/headerize.tmp
    NEWSIZE=$(stat --format %s /tmp/headerize.tmp)
    EXPECTEDSIZE=$(($HEADERSIZE+$OLDSIZE))
    if [ "$NEWSIZE" -eq "$EXPECTEDSIZE" ]; then
      mv /tmp/headerize.tmp "$FILENAME"
    else
      echo "Something odd happened when processing $FILENAME, headerization skipped for this file."
    fi
done

あなたが非常に哀れなシステムを持っているか、長すぎる長さの基準が高すぎるのでない限り、これはまともな時間で完了するはずです. また、エラーチェックも含まれています。もちろん、ヘッダーが改行で終わっていることを確認する必要があります。そうしないと、最後のヘッダー行と最初のテキストファイル行がマージされます。

ここで残っている唯一の最適化は、一時ファイルが元のファイルと同じファイルシステムに書き込まれるようにすることです。これにより、 mv コマンドが高速化される可能性があります。

一般に、コンテンツの挿入は低速です。これは、メモリ内であってもディスク上であっても当てはまります。一定時間の解は決して見つからないと思います。ただし、実際には 1 回限りのバッチ ジョブには必要ないでしょう。

これは、IMO で Python で実行できる最速の実装です。一時ファイルを作成しないため、bash バージョンよりも高速である可能性があります。

MYHEADERPATH=/path/to/the/header
with open(MYHEADERPATH, 'r') as f:
    header = f.read()
for filename in files:
    with open(filename, 'r') as f:
        content = f.read()
    with open(filename, 'w') as f:
        f.write(header + content)

ただし、厳密に安全にしたい場合は、bash スクリプトと同じ方法で実行する必要があるため、最終的に速度の違いはほとんどない可能性があります。

于 2013-05-20T14:17:39.760 に答える