파일 A에 포함 된 줄을 얻을 수 있지만 파일 B에는없는 줄을 얻을 수있는 도구가 있습니까? 예를 들어 perl을 사용하여 약간의 간단한 스크립트를 만들 수 있지만, 이와 같은 것이 이미 존재하면 지금부터 시간을 절약 할 수 있습니다.
파일 A에 포함 된 줄을 얻을 수 있지만 파일 B에는없는 줄을 얻을 수있는 도구가 있습니까? 예를 들어 perl을 사용하여 약간의 간단한 스크립트를 만들 수 있지만, 이와 같은 것이 이미 존재하면 지금부터 시간을 절약 할 수 있습니다.
답변:
예. grep
텍스트 문자열에 대한 파일 검색을위한 표준 도구를 사용하여 한 파일의 모든 줄을 다른 파일에서 뺄 수 있습니다.
grep -F -x -v -f fileB fileA
이것은 fileB의 각 행을 패턴 ( -f fileB
)으로 사용하고 일반 정규식이 아닌 일반 문자열로 처리하여 작동합니다 ( -F
). 전체 줄 ( -x
) 에서 일치하도록 강제하고 일치 하지 않는 줄 ( ) 만 인쇄합니다 -v
. 따라서 fileB의 행과 동일한 데이터를 포함하지 않는 fileA의 행을 인쇄합니다.
이 솔루션의 단점은 라인 순서를 고려하지 않으며 입력에 다른 위치에 중복 라인이 있으면 예상 한 것을 얻지 못할 수 있다는 것입니다. 이에 대한 해결책은과 같은 실제 비교 도구를 사용하는 것 diff
입니다. 파일에서 행의 100 %에 컨텍스트 값으로 diff 파일을 작성한 다음 파일 A를 파일 B로 변환 할 때 제거 될 행에 대해 구문 분석하여이를 수행 할 수 있습니다 (이 명령은 diff도 제거합니다) 올바른 줄을 얻은 후 서식을 지정하십시오.)
diff -U $(wc -l < fileA) fileA fileB | sed -n 's/^-//p' > fileC
-u
인수는 공백이 없는 한 실제로는 숫자의 매개 변수를 사용합니다. 이전에 사용했던 방식의 장점은 값과 함께 또는 값없이 작동하므로 출력되지 않은 리턴 된 하위 명령 루틴에서 무언가를 사용할 수 있다는 것입니다. 반면 대문자 '-U'는 인수가 필요합니다.
diff
파이프 라인은 치료 덕분에 작동합니다.
grep
필요에 따라 각 파일을 처리 할 수 있습니다 . 예 :grep -F -x -v -f <(sort fileB) <(sort fileA)
diff
파일의 위치가 고려된다는 것입니다.
대답은 비교할 파일의 형식과 형식에 따라 다릅니다.
비교중인 파일이 정렬 된 텍스트 파일 인 경우 Richard Stallman과 Davide McKenzie가 작성한 GNU 도구가 comm
사용자가 수행 한 필터링을 수행 할 수 있습니다. coreutils의 일부입니다.
다음 2 개의 파일이 있다고 가정하십시오.
$ cat a
1
2
3
4
5
$ cat b
1
2
3
4
5
6
파일 b
에없는 파일의 행 a
:
$ comm <(sort a) <(sort b) -3
6
comm
; 불행히도, comm
정렬 된 파일이 필요합니다
<()
? 그것은 효과가 있고 그것을 얻지만이 이상한 이름이 있습니까?
comm
원래는 1973 년경 RMS가 아닌 Bell Labs의 누군가에 의해 작성되었습니다. 나중에 많은 GNU 구현을 언급하고 있습니다. 수년에 걸쳐 유닉스 유틸리티의 많은 구현이 있었다.
grep 및 comm (정렬) 방법은 큰 파일에서 시간 이 오래 걸립니다. SiegeX와 ghostdog74 는 Stack Overflow에서 두 파일 중 하나에 고유 한 행을 추출하는 두 가지 훌륭한 방법을 공유했습니다 .
$ awk 'FNR==NR{a[$0]++}FNR!=NR && !a[$0]{print}' file1 file2
$ awk 'FNR==NR{a[$0]++;next}(!($0 in a))' file1 file2