리눅스 : 파일을 비교하지 않고 디렉토리 구조 비교


55

실제로 파일의 데이터를 비교하지 않고 두 디렉토리 구조를 비교하는 가장 쉽고 간단한 방법은 무엇입니까? 이것은 잘 작동합니다 :

diff -qr dir1 dir2_

그러나 파일도 비교하기 때문에 실제로 느립니다. diff 또는 다른 간단한 cli 도구를위한 스위치가 있습니까?


"디렉토리 구조"란 디렉토리 경로 또는 디렉토리와 비 디렉토리 파일의 경로만을 의미합니까?
intuited

예, 폴더 파일
요나

1
이 경우 -type d@slartibartfast의 답변에서 옵션을 제거 하거나 내 답변을 확인해야합니다.
17:52에

답변:


36

다음 (디렉토리 1의 첫 번째 디렉토리와 디렉토리 2의 두 번째 디렉토리를 대체하는 경우)은 원하는 것을 신속하게 수행해야합니다.

find directory1 -type d -printf "%P\n" | sort > file1
find directory2 -type d -printf "%P\n" | sort | diff - file1

기본 원칙은 기본 디렉토리 N 디렉토리에 상대적인 서브 디렉토리 경로를 포함하여 모든 디렉토리를 인쇄하는 것입니다.

일부 디렉토리 이름에는 캐리지 리턴이 있지만 다른 디렉토리 이름에는 캐리지 리턴이 없으면 결과가 떨어질 수 있습니다 (와이어드 출력 생성).


하나의 디렉토리에 수천 개의 파일이있는 폴더가 들어 있으면 디렉토리가 모두 개별적으로 나열 diff -rq되고 루트 디렉토리가 하나에 존재하고 계속 수행한다는 것을 보여 주기 때문에 이것은 나에게 좋지 않습니다 .
크리스 제퍼슨

직감적으로 지적한 바와 같이 (OPs 질문에 대답하기 위해, -type d는 디렉토리뿐만 아니라 비교에서도 파일이 고려되도록 -d를 제거해야한다)
user2746401

나는 문제 진술을 읽는 것을 이해하고 존중합니다. 당시에는 제가 읽지 않았습니다. 업데이트 된 질문에 응답하기 위해 답변을 편집 할 것을 권장합니까? 나는 그것이 어떤 사람들에게 도움이 될 것이라고 생각한다면 그렇게 할 수 있으며, 해결책과 의견을 남겨두고 현재의 방식을 설정하는 것이 좋습니다. 이는 합리적으로 효과적입니다.
Slartibartfast

34
vimdiff <(cd dir1; find . | sort) <(cd dir2; find . | sort)

공통 섹션이 접혀있는 두 디렉토리 계층 구조를 나란히 표시합니다.


이 솔루션은 무작위로 실패합니다. vim이 임시 파일 디스크립터를 읽거나 다시 읽을 때 이미 사라졌습니다.
Denilson Sá Maia

23

나는 보통 rsync이 작업에 사용 합니다 :

rsync -nav --delete DIR1/ DIR2

아주 조심 항상 사용하려면-n, 일명--dry-run디렉토리를, 옵션을하거나 동기화합니다 (의 내용을 변경).

이것은 파일 수정 시간과 크기를 기준으로 파일을 비교합니다 ... 나는 그것이 정말로 원하는 것이라고 생각 합니다. 파일 내용의 차이를 무시하기 위해 더 빨리 일어나기를 원하지 는 않습니다. 동일한 이름을 가진 다른 파일을 나열하지 않으려면 --ignore-existing옵션을 추가 하면 그렇게 할 것이라고 생각합니다.

또한 퍼팅하지 않는 것이 인식 /의 끝에 것은 DIR1그것이 비교하게됩니다 디렉토리를 DIR1내용DIR2.

결과는 약간 장황하지만 결과적으로 어떤 파일 / 디렉토리가 다른지 보여줍니다. 존재 DIR2하거나 존재 하지 않는 파일 / 디렉토리 DIR1에는 단어가 앞에 붙습니다 deleting.

어떤 경우에는 @slartibartfast의 답변이 더 적합 할 수 있지만 -type d디렉토리가 아닌 파일 목록을 활성화하려면 옵션을 제거해야 합니다. rsync비교할 파일 / 디렉토리 수가 많으면 더 빠릅니다.


훌륭한 답변입니다. rsync의 출력에서는 deleting...텍스트 를 알아 채기가 어렵지만 속도를 유지하면서 파일을 비교하는 더 좋은 방법 중 하나 일 수 있습니다. OP의 예에서와 같이 파일을 비교할 필요가 없으면 다른 답변이 더 빠르지 만 실제로이 것을 좋아합니다.
Joel Mellon

이것이 내가 추구 한 것입니다. 거대한 디렉토리 트리 쌍에 크기가 다른 파일이 몇 개 있었으며 어느 파일이 있는지 알고 싶었습니다. 이것은 단 몇 초 만에 목표를 달성했습니다.
suprjami

읽기 전용 액세스 권한이있는 사용자로 실행하는 것이 좋습니다. sudo -u nobody rsync -nav --delete d1 d2'others'에 대한 플래그가 읽기를 허용하는 경우 와 같습니다 .
user1182474

이 솔루션을 실행할 때 "파일 목록 작성 중 ... 완료 \ n X 바이트를 수신함 Y 바이트 Z 바이트 / 초 총 크기는 A 속도 향상입니다"(여기서는 XYZAB를 숫자로 대체했습니다). 그것은 모든 것이 동일하다는 것을 의미합니까? 더 구체적인 내용은 언급하지 않았습니까? 미리 감사드립니다
Scott H

내 자신의 질문에 대답하기 위해 각각 다른 파일을 추가하는 실험을 해 보았으며 출력에 언급 된 특정 파일 / 디렉토리가 모두 동일한 것을 의미하지 않는 것으로 보입니다.
Scott H

18

ls 답변과 비슷하지만 트리 를 설치 하면

tree dir1 > out1
tree dir2 > out2
diff out1 out2

7
또는 tmpfile을 피하기 위해diff <( tree dir1 ) <( tree dir2 )
Joel Mellon

1
i트리 라인 ( tree -i dir1, 등)을 인쇄하지 않는 플래그로 tree를 실행하는 것이 좋습니다 . 디렉토리 구조가 한 곳에서 다른 경우 일치하는 다른 파일 |은 트리 출력에 더 많거나 적은 기호를 가질 수 있으며 diff는 파일 경로가 동일한 경우에도 해당 줄을 잡습니다.
askewchan

2
diff <(tree -i dir1) <(tree -i dir2)가 가장 좋은 답입니다. 질문에 파일 내용을 읽지 말라고 명시 적으로 diff 또는 rsync를 제안하는 모든 답변을 다운 투표하고 싶습니다. 참고 : 두 개의 파이프를 사용하려면 브래킷 사이에 공간을주의해서 사용해야합니다. 예를 정확하게 따르십시오. 예를 들어 백업 후 두 개의 20G 볼륨을 비교하기 위해 트리 응답에 약 5 초가 걸렸습니다. 나머지는 20 분 이상 걸렸습니다.
Jason Morgan

3

나는이 문제에 대한 해결책을 찾고있었습니다. 내가 가장 좋아하는 솔루션은 다음과 같습니다.

comm <(ls DIR1) <(ls DIR2)

여기에는 3 개의 열이 있습니다. 1-DIR1의 파일 만, 2-DIR2의 파일 만, 3-DIR3의 파일 자세한 내용은이 블로그 게시물을 참조하십시오 .


어디에 DIR3지정되어 있습니까? 내가 보는 모든이다 DIR1DIR2.
Michael Dorst

나는 출력했다 (I 무엇을 말할 수에서) 그것을 시도하고, 모든 파일 만에서 DIR1열 1 만 모든 파일 DIR2열이 , 모든 파일을 모두 공유열 3 . 그것은 유용하지만, 3 열을 어떻게 제거 하고 차이점 만 남길 수 있는지 알고 있습니까? 정렬 할 파일 이 많이 있으며 대부분 동일합니다. 나는 같은 것을 볼 필요가 없습니다.
Michael Dorst

1
또한 comm <(ls DIR1) <(ls DIR2)재귀 적으로 작동하지 않는 것으로 나타났습니다 . 나는 그것을 사용했다 comm <(ls -R1 DIR1) <(ls -R1 DIR2). ls -R디렉토리를 재귀 적으로 탐색하고 ls -1( L이 아닌 하나임 ) 한 줄에 하나의 파일 이름 만 인쇄합니다. ls
Michael Dorst

@ 마이클 : comm -3(참조 man comm).
Zaz

2
ls > dir1.txt

ls > dir2.txt

그런 다음 두 목록을 비교하십시오.


OP가 경로의 계층 구조를 원하는 것처럼 보입니다. 이것은 현재 디렉토리의 모든 파일을 비교합니다. 그가 단지 디렉토리를 원한다는 것은 논쟁의 여지가 있지만 가능하다. 그는 파일의 내용보다는 파일 이름을 원할 수도 있습니다.
intuited

@intuited-당신이 맞아요. 나는 그것을 잘못 읽었다.
MDMarra

2

이것은 최적의 솔루션입니다

diff --brief -r dir1 dir2

--brief 스위치는 차이점에 대한 세부 정보가 아니라 파일이 다른지 여부 만보고합니다.


1
OP는 이미 -q질문에 있으며의 별칭입니다 --brief. 이 답변은 새로운 정보를 제공하지 않습니다.
Michael Dorst

1
OP는 파일 내용 비교를 원하지 않습니다. But it's really slow because it's comparing files too.
Joel Mellon

1

"diff -qr"을 사용하여 다른 파일을 가져온 다음 grep과의 파일 비교를 필터링하여 디렉토리 중 하나에 만있는 파일 이름 만 가져옵니다.

diff -qr dir1 dir2 | grep -v "Files.*differ" 

1

이것은 나무에서 일치하는 것으로 예상되는 누락 된 파일을 찾아야하는 특정 요구에 효과적이었습니다.

diff <( cd dir1; find * |sort ) <(cd dir2; find * | sort)

-3

나는 rsync 만 userfull이라고 생각합니다. 왜?

diff는 파일과 디렉토리를 유지하는 구조에만 유용합니다. Diff는 심볼릭 링크를 사용할 때 적절한 종료 코드를 제공하지 않습니다. 이 경우 diff는 src와 dst가 동일한 경우에도 2 개의 종료 코드를 반환 할 수 있습니다 (시간, 크기, 이름, 타임 스탬프, 포인팅 소프트 링크 등).

dir, 파일 시스템은 src와 dst의 디렉토리 내용이 동일하더라도 파일 순서를 보장하지 않습니다. 어쩌면 ls 출력을 정렬하여 필터링해야 할 수도 있습니다. 그러나 pure ls는 노드 이름 만 표시합니다.

노드 유형에 대해 diff, cmp, test -X를 포함한 스크립트가 유용 할 수 있지만 많은 test / cmp 실행으로 인한 과부하에 대해 기억하십시오. 스크립트 속도가 매우 느립니다.

평소와 같이 "dirs is / isn 같지 않음"이라는 간단한 정보를 얻으려면 -n (dry) 옵션과 함께 rsync를 사용해야합니다. 다른 것을 찾으려면 diff 명령을 사용하십시오.


왜 마이너스인지 알고 싶습니다.
Znik
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.