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
どのように:
- フィールド区切り記号を次のように設定します。
,
FNR=NR
最初のファイルが処理されている間。この例では、Vin番号は値1に関連して読み取られます。その後、next
残りのコードをスキップしてください。最初のファイル以降のすべてのファイルに対して、レコード番号9(vin)が関連配列にない場合は、その行を印刷します。
答え4
grep
これには十分です。
grep -vFf vinlist data.csv
ただし、サンプルテキストにはvinlistに末尾の空白が含まれているため、削除してください。 (bashまたはプロセス代替構文を持つ他のシェルを想定)
grep -vFf <(sed -r 's/^[[:blank:]]+|[[:blank:]]+$//g' vinlist) data.csv