2012-10-17 5 views
1

2 개의 큰 CSV 파일로 작업하고 있습니다. 더 작은 것은 큰 것의 부분 집합입니다. 첫 번째 필드는 고유하지 않은 키이며 customerID입니다.grep을 사용하여 파일에서 다른 파일의 키가있는 행을 제거합니다.

필드 1에서 동일한 값을 가진 큰 파일의 모든 줄을 작은 파일로 찾은 다음이 결과와 원래의 부분 집합 사이의 델타를 찾고 싶습니다.

그런 다음 델타에있는 필드 1에 값이있는 모든 행을 원래 하위 집합에서 제거하려고합니다.

다른 말로하면 : 큰 원본 파일에는 있지만 더 작은 부분 집합에는 존재하지 않는 행에 존재하는 custromerID가있는 원래의 더 작은 하위 집합에서 행을 제거하고 싶습니다.

나는 현재 아래와 같이 그 일을하고, 그 결과는 0

분명 내 논리에 결함이 왜 이해가 안 돼요,이 명확하게이 작업을 수행하는 가장 우아한 방법이 아니다 , 제발, 나는 더 좋은 방법을 제안 할 수있다.

파일 : full.csv는

,1052,tec101,UNIX 
,1052,ser303,UNIX 
,1052,backu2,UNIX 
,1052,sma114,UNIX 
,1052,appsup,UNIX 
,1052,emails,UNIX 
,1059,marygs,UNIX 
,39835,deepr2,UNIX 
,44536,hai499,UNIX 
,1274,lemo27,Windows 
,48567,wdanro,UNIX 
,81860,pro846,UNIX 
,1419,graphe,UNIX 
,83999,doerf1,UNIX 
,1551,taxtri,UNIX 
,1572,lodes4,UNIX 
,1603,wes244,Windows 
,102888,law642,UNIX 
,1700,au2960,UNIX 

파일 : 내가 지금 뭘하는지 subset.csv

,1052,sma114,UNIX 
,1052,appsup,UNIX 
,1052,emails,UNIX 
,1059,marygs,UNIX 
,39835,deepr2,UNIX 
,44536,hai499,UNIX 
,1274,lemo27,Windows 
,48567,wdanro,UNIX 
,81860,pro846,UNIX 
,1419,graphe,UNIX 

:

[[email protected] sandbox]$ wc -l * 
19 full.csv 
10 subset.csv 
29 total 
[[email protected] sandbox]$ cat subset.csv | awk -F, '{print ","$2","}' > subset_keys 
[[email protected] sandbox]$ grep -F -f subset_keys full.csv | wc -l 
13 
[[email protected] sandbox]$ grep -F -f subset_keys full.csv | head -n2 
,1052,tec101,UNIX 
,1052,ser303,UNIX 
[[email protected] sandbox]$ grep -F -f subset_keys full.csv > subset_keys_grep 
[[email protected] sandbox]$ cat subset_keys_grep | awk -F, '{print ","$2","}' | head -n2 
,1052, 
,1052, 
[[email protected] sandbox]$ cat subset_keys_grep | awk -F, '{print ","$2","}' | wc -l 
13 
[[email protected] sandbox]$ cat subset_keys_grep | awk -F, '{print ","$2","}' > keys_to_remove 
[[email protected] sandbox]$ grep -F -f keys_to_remove subset.csv | wc -l 
10 
[[email protected] sandbox]$ grep -F -f keys_to_remove subset.csv > lines_to_remove 
[[email protected] sandbox]$ grep -Fv -f lines_to_remove subset.csv | wc -l 
0 

내 예상 결과 7, 또는한다 , 카운트없이, 다음 :

,1059,marygs,UNIX 
,39835,deepr2,UNIX 
,44536,hai499,UNIX 
,1274,lemo27,Windows 
,48567,wdanro,UNIX 
,81860,pro846,UNIX 
,1419,graphe,UNIX 

결과는 하위 집합에만 존재하고 전체 파일의 다른 위치에는 존재하지 않는 customerID가있는 하위 집합의 7 개 행이어야합니다.

+0

나는 당신이하려는 것을 잘 따르지 않습니다.문제의 두 파일과 같이 구체적인 단축 예를 추가하는 것이 도움이 될 수 있지만 짧은 파일은 10 줄, 긴 파일은 20 줄입니다. 그런 다음 해당 파일이 제안 된 프로세스 및 결과에 어떻게 부합하는지 예상하십시오. – danfuzz

+0

좋아, 좀 더 간단한 예를 생각해 보겠다. 실제 파일에는 민감한 정보가 들어있어, 서브넷을 제공 할 수는 없다. –

+0

예제를 단순화했습니다 –

답변

1

시도해보십시오.

$ cat full1.csv 
,1052,sma114,UNIX 
,1052,appsup,UNIX 
,1052,emails,UNIX 
,1059,marygs,UNIX 
,39835,deepr2,UNIX 
,44536,hai499,UNIX 
,1274,lemo27,Windows 
,48567,wdanro,UNIX 
,81860,pro846,UNIX 
,1419,graphe,UNIX 
,83999,doerf1,UNIX 
,1551,taxtri,UNIX 
,1572,lodes4,UNIX 
,1603,wes244,Windows 
,102888,law642,UNIX 
,1700,au2960,UNIX 

너무 요구 사항이 1 키는 subset.csv 파일에 여러 번 나타나는 경우에 조금 더 눈에 띄는 : 나는 처음 3 줄을 제거하기 위해 귀하의 의견 "full.csv"를 수정했습니다. subset.csv 파일의 줄 순서가 full.csv 파일의 순서와 일치한다고 가정합니다. 그런 경우가 아니라면 그냥
$ cat test.awk      
BEGIN{ FS="," } 
NR==FNR { key2full[$2] = key2full[$2] $0 ORS; next } 
{ key2subset[$2] = key2subset[$2] $0 ORS } 
END { 
    for (key in key2subset) { 
     if (key2subset[key] == key2full[key]) { 
     printf "%s", key2subset[key] 
     } 
    } 
} 
$ awk -f test.awk full1.csv subset.csv 
,1052,sma114,UNIX 
,1052,appsup,UNIX 
,1052,emails,UNIX 
,1419,graphe,UNIX 
,44536,hai499,UNIX 
,48567,wdanro,UNIX 
,1274,lemo27,Windows 
,81860,pro846,UNIX 
,39835,deepr2,UNIX 
,1059,marygs,UNIX 

내가 위의 수정 입력 파일 내 명령을 실행하여 혼란을 야기 것 같다 ... 문자열을 분할하는 비틀기를합니다. 이 트릭을 할해야

$ cat full.csv 
,1052,tec101,UNIX 
,1052,ser303,UNIX 
,1052,backu2,UNIX 
,1052,sma114,UNIX 
,1052,appsup,UNIX 
,1052,emails,UNIX 
,1059,marygs,UNIX 
,39835,deepr2,UNIX 
,44536,hai499,UNIX 
,1274,lemo27,Windows 
,48567,wdanro,UNIX 
,81860,pro846,UNIX 
,1419,graphe,UNIX 
,83999,doerf1,UNIX 
,1551,taxtri,UNIX 
,1572,lodes4,UNIX 
,1603,wes244,Windows 
,102888,law642,UNIX 
,1700,au2960,UNIX 

$ awk -f test.awk full.csv subset.csv 
,1419,graphe,UNIX 
,44536,hai499,UNIX 
,48567,wdanro,UNIX 
,1274,lemo27,Windows 
,81860,pro846,UNIX 
,39835,deepr2,UNIX 
,1059,marygs,UNIX 
+0

전체 파일 OTHER에 ELSEWHERE 키가있는 하위 집합 행을 찾고 싶습니다. 그런 다음 하위 집합에서이 행을 제외하려고합니다. –

+0

나는 내 대답을 편집했다. –

+0

고맙습니다. 혼란스러워서 죄송합니다. –

0

: 여기 그래서 여기가 원하는 출력을 생성 않는 것을 보여주기 위해 원본 파일에 대해 실행중인 원래에

grep -v -f subset.csv full.csv | awk -F, '{print ","$2",";}' >keys.csv 
grep -v -f keys.csv subset.csv 
0

명세서를 바탕으로 그 subset.csv의 모든 레코드가 full.csv에 존재하므로 다음은 bash에서 작동해야합니다. 먼저 uniq을 사용하여 full.csv에서 유효한 CustomerID를 식별합니다. 이것은 필터링을 위해 subset.csv를 다시 결합한 것입니다.

join -o 2.1,2.2,2.3,2.4 -v 2 -t, -1 2 -2 2 <(sort full.csv subset.csv | uniq -u | 
sort -k2,2 -t,) <(sort -k2,2 -t, subset.csv) 
관련 문제