다른 파일의 값을 포함하지 않는 한 파일의 행 선택

다른 파일의 값을 포함하지 않는 한 파일의 행 선택

두 개의 파일이 있습니다. 하나는 60490개의 데이터 행을 포함하는 CSV입니다. 각 행은 고객 이름, 서비스 날짜 등과 같은 값 집합입니다.

첫 번째 파일의 이러한 값 중 하나는 VIN 값입니다.

92809 VIN 목록이 포함된 두 번째 큰 파일이 있습니다.

두 번째 파일의 VIN을 나열하는 첫 번째 파일의 모든 줄을 제거하는 방법을 찾아야 합니다.

아래에서 grep을 시도했습니다. 이것은 내가 예상한 대로 작동하지만 매우 느리고 약 50줄의 출력 후에 OS에 의해 종료됩니다.

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

이를 달성하는 가장 빠른 방법은 무엇입니까? 조사하는 동안 찾은 모든 것은 완전히 정렬된 데이터가 필요하거나 두 파일에 동일한 행이 있거나 시간이 오래 걸리거나 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를 사용하여 두 파일에서 공통 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

관련 정보