A 파일에 있는 데이터중 B 파일에 없는 것만 뽑기?

달파란의 이미지

Quote:
# cat A.txt
aaa
bbb
ccc
ddd
eee
fff
ggg

# cat B.txt
111
aaa
222
bbb
ccc


위와 같은 파일이 있을 때, 아래와 같이
A.txt 에 있는 데이터중 B.txt 에 없는 것만 뽑는 방법이 있을까요?
Quote:
#cat result.txt
ddd
eee
fff
ggg
alfalf의 이미지

diff A.txt B.txt | sed -n '/^</s/^< //p'

정지용의 이미지

파일 크기에 따라 효율성은 달라질 수 있겠지만, 간단하게 python으로 짜보면...

fileA = open('a.txt')
fileB = open('b.txt')
fileResult = open('result.txt','w')

a = fileA.readlines()
b = fileB.readlines()

result = filter(lambda x:not x in b, a)
fileResult.writelines(result)

fileA.close()
fileB.close()
fileResult.close()

여튼 일반적으로 생각한다면, 파일 하나를 메모리에 다 읽어들인다음, 나머지 파일을 한 줄씩 읽으면서 일치하는 것을 지워나가거나 없는 것을 추가하거나 하는 방식이면 될 것 같습니다.

쉘 스크립트로 grep -v 를 이용해서 짜는 방법도 있겠고, perl 등을 이용한다면 더 간단해지겠죠~

파일의 sort 상태가 상관없다면 sort 시켜서 윗분 말씀처럼 diff를 사용하면 아름답겠네요 ^^;;

;)

최종호의 이미지

comm -23 file1 file2

하시면 file1 에만 있는 내용을 보실 수 있습니다.

file1과 file2는 정렬되어있다고 가정합니다.

comm 맨페이지를 참고하세요..

실행시에 임시파일을 생성할 수 있는 쉘구문이 있었던 것 같은데 잘 안 찾아지네요.

comm -23 @sort file1@ @sort file2@

# @ @ 는 무언가 모를 임시파일 생성 구문을 넣으면 될텐데... 생각이 안나네요.. 이렇게 두번 쓸 수 있는지도 확실치 않고.. ㅡ.ㅡ;;

alfalf의 이미지

최종호 wrote:

comm -23 @sort file1@ @sort file2@

# @ @ 는 무언가 모를 임시파일 생성 구문을 넣으면 될텐데... 생각이 안나네요.. 이렇게 두번 쓸 수 있는지도 확실치 않고.. ㅡ.ㅡ;;

BASH의 경우에는 아래와 같이 하시면 됩니다.
$ comm -23 <(sort file1) <(sort file2)

익명 사용자의 이미지

아마도 간단히 man grep해서 살펴본 결과로는

Quote:

$ grep -v -f B.txt A.txt
ddd
eee
fff
ggg
$

다만 B.txt에 빈 라인이 있을 경우, 결과에는 주의해야 합니다. 정의에 맞는 동작는 한 결과이기는 합니다만...

최종호의 이미지

alfalf wrote:
최종호 wrote:

comm -23 @sort file1@ @sort file2@

# @ @ 는 무언가 모를 임시파일 생성 구문을 넣으면 될텐데... 생각이 안나네요.. 이렇게 두번 쓸 수 있는지도 확실치 않고.. ㅡ.ㅡ;;

BASH의 경우에는 아래와 같이 하시면 됩니다.
$ comm -23 <(sort file1) <(sort file2)

재밌는 기능이네요!!

지금 찾아보니까 process substitution 이라는 기능이고,
/dev/fd 를 지원하는 OS에서만 지원되네요?
ksh, bash가 지원가능하고, Bourne sh, csh 은 지원하지 않네요.

% ls <(sort file1) <(sort file2)
/dev/fd/3 /dev/fd/5

의 결과가 나오는데, fd/4 는 어느 녀석이 먹어버리는 걸까요? :wink: