他のファイルの値を含まない限り、ファイルの行の選択

他のファイルの値を含まない限り、ファイルの行の選択

2つのファイルがあります。 1つは60490のデータ行を含むCSVです。各行は、顧客名、サービス日などの値のセットです。

最初のファイルのこれらの値の1つはVIN値です。

92809 VINのリストを含む2番目の大きなファイルがあります。

2番目のファイルのVINを一覧表示する最初のファイルのすべての行を削除する方法を見つける必要があります。

以下でgrepを試しました。これは私が期待どおりに機能しますが、非常に遅く、約50行の出力後にOSによってシャットダウンされます。

$ grep -v -f vinlist data.csv > output.csv

これを達成するための最速の方法は何ですか?調査中に見つかったすべては、完全にソートされたデータが必要であるか、2つのファイルに同じ行があるか、時間がかかるか、OSによってシャットダウンされるようです。

データ.csv

123,[email protected],JOE,BLOGGS,123456789,12345-123,"Place Name",12345,1C4NJPBB4DD122174,2014-01-20  
123,[email protected],JOE,BLOGGS,123456789,12345-123,"Place Name",12345,1GMDV33179D147281,2014-01-20  
123,[email protected],JOE,BLOGGS,123456789,12345-123,"Place Name",12345,1FUYDCYB7WP879651,2014-01-20  
123,[email protected],JOE,BLOGGS,123456789,12345-123,"Place Name",12345,1FM5K8D8XFGA82149,2014-01-20  
123,[email protected],JOE,BLOGGS,123456789,12345-123,"Place Name",12345,5TDBT48A72S003496,2014-01-20  

ディスクリスト:

JF1VA1E6XH9812361  
1HGCP26369A103521  
3N1CN7AP0CL810631  
5XYZK3AB7BG089758  
1FM5K8D8XFGA82149  
4S3BMBG61C3019520  
1FTNE24LX4HA22330  
1N4AL3AP8FC420210  
2GTEC19C491123429  
3N1CN7AP5FL944233  

答え1

行内のvinがどこにあるかを知っているので、一般的な検索を実行する必要はありません。代わりに、高速検索を可能にするためにインデックス付きデータ構造を持つVinを読み取ることができます。

Pythonを使用すると、次のことができます。

パスワード:

# read the vins into a set to allow fast lookup
with open('file3', 'rU') as f:
    vins = {vin.strip() for vin in f.readlines()}

# go through the data file one line at a time
with open('file2', 'rU') as f:
    for line in f.readlines():

        # get the vin in the line
        vin = line.split(',')[8]

        # if the vin is not in our set, print out the line
        if vin not in vins:
            print(line.strip())

結果:

123,[email protected],JOE,BLOGGS,123456789,12345-123,"Place Name",12345,1C4NJPBB4DD122174,2014-01-20
123,[email protected],JOE,BLOGGS,123456789,12345-123,"Place Name",12345,1GMDV33179D147281,2014-01-20
123,[email protected],JOE,BLOGGS,123456789,12345-123,"Place Name",12345,1FUYDCYB7WP879651,2014-01-20
123,[email protected],JOE,BLOGGS,123456789,12345-123,"Place Name",12345,5TDBT48A72S003496,2014-01-20

答え2

unix コマンド cut を使用して data.csv から vin を選択できます。次に、sortとuniq -dを使用して、2つのファイルで共通のvinを見つけます。

バッシュから:

cut -d',' -f9 > vin_data
sort vin_data vinlist | uniq -d > vin_to_delete

その後、Pythonまたは好みのスクリプト言語を使用して新しいファイルを作成できます。私のPythonスクリプト。

f=open('data_vin_removed.csv','w')
v=[i.strip() for i in open('vin_to_delete')]
for i in open('data.csv'):
    if any([j in i for j in v]):
        continue
    else:
        f.write(i)
f.close() 

これにより、vinlistにvinがないdata.csv行を含むファイルが作成されます。

答え3

使用awk:

パスワード:

awk -F, 'FNR==NR{a[$1]=1;next} !a[$9] {print}' vin_file data_file

コメントで提案されているように、よりメモリ効率の良い方法は次のとおりです。

awk -F, 'FNR==NR{a[$1];next} (!($9 in a))' vin_file data_file

どのように:

  1. フィールド区切り記号を次のように設定します。,
  2. FNR=NR最初のファイルが処理されている間。この例では、Vin番号は値1に関連して読み取られます。その後、next残りのコードをスキップしてください。

  3. 最初のファイル以降のすべてのファイルに対して、レコード番号9(vin)が関連配列にない場合は、その行を印刷します。

答え4

grepこれには十分です。

grep -vFf vinlist data.csv

ただし、サンプルテキストにはvinlistに末尾の空白が含まれているため、削除してください。 (bashまたはプロセス代替構文を持つ他のシェルを想定)

grep -vFf <(sed -r 's/^[[:blank:]]+|[[:blank:]]+$//g' vinlist) data.csv

関連情報