file1을 file2와 비교하고 file2에없는 file1의 줄을 포함하는 file3을 생성하고 싶습니다.
file1을 file2와 비교하고 file2에없는 file1의 줄을 포함하는 file3을 생성하고 싶습니다.
답변:
diff (1)은 답이 아니지만 comm (1)은 답입니다.
NAME
comm - compare two sorted files line by line
SYNOPSIS
comm [OPTION]... FILE1 FILE2
...
-1 suppress lines unique to FILE1
-2 suppress lines unique to FILE2
-3 suppress lines that appear in both files
그래서
comm -2 -3 file1 file2 > file3
입력 파일을 정렬해야합니다. 그렇지 않은 경우 먼저 정렬하십시오. 이것은 임시 파일로 할 수 있습니다.
comm -2 -3 <(sort file1) <(sort file2) > file3
쉘이 프로세스 대체를 지원하는 경우 (bash는 지원함).
comm -23
이것을 고려하십시오 :
파일 a.txt :
abcd
efgh
b.txt 파일 :
abcd
다음과 같은 차이점을 찾을 수 있습니다.
diff -a --suppress-common-lines -y a.txt b.txt
출력은 다음과 같습니다.
efgh
다음을 사용하여 출력 파일 (c.txt)의 출력을 다시 추출 할 수 있습니다.
diff -a --suppress-common-lines -y a.txt b.txt > c.txt
이것은 귀하의 질문에 답할 것입니다.
"... file2에없는 file1의 행을 포함합니다."
-d
것 diff
입니다. -i
, -E
, -w
, -B
및 --suppress-blank-empty
도 있지만 항상 그렇지는 때때로 유용 할 수 있습니다. 사용 사례에 맞는 것이 무엇인지 모르겠다면 diff --help
먼저 시도해보십시오 (일반적으로 명령이 무엇을 할 수 있는지 모를 때 좋은 생각입니다).
때로는 diff
필요한 유틸리티이지만 때로는 join
더 적절합니다. 파일은 미리 정렬되어야하며 bash, ksh 또는 zsh와 같은 프로세스 대체를 지원하는 쉘을 사용하는 경우 즉시 정렬을 수행 할 수 있습니다.
join -v 1 <(sort file1) <(sort file2)
시험
sdiff file1 file2
일반적으로 대부분의 경우 훨씬 더 잘 작동합니다. 줄 순서가 중요하지 않은 경우 (예 : 일부 텍스트 구성 파일) 파일을 먼저 정렬 할 수 있습니다.
예를 들면
sdiff -w 185 file1.cfg file2.cfg
sdiff <(sort file1) <(sort file2)
)
coreutils로이 문제를 해결해야하는 경우 허용되는 답변이 좋습니다.
comm -23 <(sort file1) <(sort file2) > file3
정렬이나 처리 대체가 필요하지 않고 무한 스트림을 지원 하는 sd (stream diff) 도 사용할 수 있습니다 .
cat file1 | sd 'cat file2' > file3
아마도이 예에서 그다지 많은 이점은 아니지만 여전히 고려하십시오. 어떤 경우에는 comm
또는 을 사용할 수 grep -F
없습니다 diff
.
여기에 sd를 소개하는 터미널의 diffing stream에 대해 쓴 블로그 포스트가 있습니다.
이미 많은 답변이 있지만 완벽한 IMHO는 없습니다. Thanatos의 대답은 한 줄에 추가 문자를 남기고 Sorpigal의 대답은 파일을 정렬하거나 미리 정렬해야하므로 모든 상황에서 적절하지 않을 수 있습니다.
나는 다른 아무것도 다른 (여분의 문자, 아니 재정렬)없는 라인을 얻을 수있는 가장 좋은 방법의 조합이라고 생각 diff
, grep
그리고 awk
(또는 유사).
행에 "<"가 포함되지 않은 경우 짧은 한 줄은 다음과 같습니다.
diff urls.txt* | grep "<" | sed 's/< //g'
그러나 이것은 줄에서 "<"(보다 작음, 공백)의 모든 인스턴스를 제거합니다. 항상 괜찮은 것은 아닙니다 (예 : 소스 코드). 가장 안전한 옵션은 awk를 사용하는 것입니다.
diff urls.txt* | grep "<" | awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}'
이 한 줄짜리 파일은 두 파일을 비교 한 다음 diff의 ed 스타일 출력을 필터링 한 다음 diff가 추가하는 후행 "<"를 제거합니다. 줄에 "<"자체가 포함되어 있어도 작동합니다.
diff a1.txt a2.txt | grep '> ' | sed 's/> //' > a3.txt
이 스레드에서 거의 모든 답변을 시도했지만 완료되지 않았습니다. 하나 위의 몇 가지 흔적이 나를 위해 일했습니다. diff 는 당신에게 차이 를 줄 것이지만 원치 않는 특별한 캐릭터가 있습니다. 실제 차이 라인은 '>'로 시작합니다. 그래서 다음 단계는 grep 라인이 '>'로 시작하고 sed로 동일한 것을 제거하는 것 입니다.
<
. 입력 파일의 순서를 바꾸면 이것을 볼 수 있습니다. 이 작업을 수행하더라도 grep
more sed를 사용하여 생략 할 수 있습니다 .`diff a1 a2 | SED '/> / S ///' '이 여전히 포함 라인 깰 수 >
또는 <
권리 상황과 여전히 줄 번호를 설명하는 추가 라인을 떠난다. 이 접근법을 시도하고 싶다면 더 나은 방법은 다음과 같습니다 diff -C0 a1 a2 | sed -ne '/^[+-] /s/^..//p'
.