1

たとえば、数字を含む大きなファイルがあります。

cat $file
3120987654
3106982658
3420787642
3210957659
3320987654
3520987654
    .
    .
    .

毎日、大きなファイルのいくつかの番号を抽出し、この日付番号を 2 番目のファイルに保存します。毎日、大きなファイルのソース データに新しい数値が追加されます。抽出ジョブ用のフィルターを作成して、既に抽出した数値を抽出しないようにする必要があります。bash または pythonスクリプトとしてこれを行うにはどうすればよいですか?

注: ソース データの「大きなファイル」から数字を削除することはできません。ファイルから数字を抽出し終えると、翌日の仕事のために元のデータと更新されたデータが必要になるため、そのままにしておく必要があります。ファイルのコピーを作成し、コピーの番号を削除すると、追加された新しい番号は考慮されません。

4

4 に答える 4

2

大きなファイルからすべての数値をセットに読み込み、それに対して新しい数値をテストします。

with open('bigfile.txt') as bigfile:
    existing_numbers = {n.strip() for n in bigfile}

with open('newfile.txt') as newfile, open('bigfile.txt', 'w') as bigfile:
    for number in newfile:
        number = number.strip()
        if number not in existing_numbers:
            bigfile.write(number + '\n')

bigfileこれにより、可能な限り効率的な方法で、まだ末尾にない数字が追加されます。

bigfile上記を効率的に実行するには大きすぎる場合は、代わりにデータベースを使用する必要があります。

于 2013-07-27T15:15:59.447 に答える
1

ソース ファイルと抽出されたデータの並べ替えられたバージョンを一時ファイルに保存できます。標準の POSIX ツールを使用してcomm、共通の行/レコードを表示できます。これらの行レコードは、後続の抽出ジョブで使用する「フィルター」の基礎になります。コマンドをsource.txt使用してファイルからレコードを抽出している場合は、スクリプトの一部のようなものになります。最良の結果を得るには、およびファイルをソートする必要があります。$SHELLgrep -v [list of common lines]source.txtextracted.txt

comm以下は、典型的な出力の簡単なカット アンド ペーストです。このシーケンスは、「大きなファイル」、抽出されたデータ、そしてファイルcommに固有の行を示す最後のコマンドを示していsource.txtます (動作については、を参照man comm(1)してくださいcomm)。grep続いて、共通ファイルを除外する「フィルタ」として任意のパターンを使用して検索する例を示します。

% cat source.txt                           
3120987654
3106982658
3420787642
3210957659
3320987654
3520987654
3520987754
3520987954
3520988654
3520987444

% cat extracted.txt 
3120987654
3106982658
3420787642
3210957659
3320987654

% comm -2 -3 source.txt extracted.txt  # show lines only in source.txt
3520987754
3520987954
3520988654
3520987444

comm2 つのファイルに共通する行を選択または拒否します。このユーティリティは、IEEE Std 1003.2-1992 (「POSIX.2」) に準拠しています。で使用するために出力を保存できますgrep

% comm -1 -2 source.txt extracted.txt | sort > common.txt
% grep -v -f common.txt source.txt | grep -E ".*444$"

これによりgrep、と に共通するファイルとsource.txt除外行が削除されます。次にパイプ ( ) を実行し、これらの「フィルター処理された」結果を抽出して新しいレコードを取得します (この場合、「444」で終わる行または行)。ファイルが非常に大きい場合、または元のファイルと抽出されたデータの数字の順序を維持したい場合は、質問がより複雑になり、応答がより複雑になる必要があります。source.txtextracted.txt|grep

私の他の応答または を使用する単純な代替アプローチの開始を参照してくださいperl

于 2013-07-27T15:16:15.280 に答える
0

一意の値を求めているわけではないと思いますが、ファイルを最後に表示してから追加されたすべての新しい値が必要ですか?

BigFile が常に新しいデータを取得すると仮定します。

DailyFilemm_dd_yy に、過去 24 時間に受信した新しい番号を含める必要があります。

このスクリプトは、あなたが望むことを行います。毎日実行してください。

BigFile=bigfile
DailyFile=dailyfile
today=$(date +"%m_%d_%Y")
# Get the month, day, year for yesterday.
yesterday=$(date -jf "%s" $(($(date +"%s") - 86400)) +"%m_%d_%Y")

cp $BigFile $BigFile$today
comm -23 $BigFile $BigFile$yesterday > $DailyFile$today
rm $BigFile$yesterday

comm両方のファイルにない行を示しています。

通信の例:

#values added to big file
echo '111
222
333' > big

cp big yesterday

# New values added to big file over the day
echo '444
555' >> big

# Find out what values were added.
comm -23 big yesterday > today
cat today

出力

444
555
于 2013-07-27T22:51:29.763 に答える