Đưa ra hai cây thư mục, làm thế nào tôi có thể tìm ra các tệp khác nhau theo nội dung?


786

Nếu tôi muốn tìm sự khác biệt giữa hai cây thư mục, tôi thường chỉ thực hiện:

diff -r dir1/ dir2/

Điều này xuất ra chính xác sự khác biệt giữa các tập tin tương ứng. Tôi quan tâm đến việc nhận danh sách các tệp tương ứng có nội dung khác nhau. Tôi cho rằng đây đơn giản chỉ là vấn đề chuyển một tùy chọn dòng lệnh đến diff, nhưng tôi không thể tìm thấy bất cứ điều gì trên trang man.

Bất kỳ đề xuất?



1
Đối với một trong các thư mục, làm thế nào để chỉ lấy các tệp / thư mục bổ sung trong thư mục kia?
Sandeepan Nath

sử dụng dircmplệnh trên unix (không phải linux)
roblogic

Câu trả lời:


1119

Bạn đã nói Linux, vì vậy bạn may mắn ra ngoài (ít nhất là nó nên có sẵn, không chắc chắn khi nó được thêm vào):

diff --brief --recursive dir1/ dir2/ # GNU long options
diff -qr dir1/ dir2/ # common short options

Nên làm những gì bạn cần.

Nếu bạn cũng muốn thấy sự khác biệt cho các tệp có thể không tồn tại trong một trong hai thư mục:

diff --brief --recursive --new-file dir1/ dir2/ # GNU long options
diff -qrN dir1/ dir2/ # common short options

12
Đẹp. Nhưng ngắn hơn là diff -qr dir1/ dir2/và phiên bản mở rộng của tôi thànhdiff -qr dir1/ dir2/ | grep ' differ'
sobi3ch

1
@skv tại sao? Đó là lệnh tương tự như câu trả lời. Tôi chỉ thay đổi thành --briefphím tắt -q.
sobi3ch

2
@skv Không chính xác những gì câu hỏi ban đầu hỏi, nhưng cập nhật câu trả lời để phù hợp với câu hỏi này là tốt.
Mark Loeser

3
@MikeMaxwell Nó cần phải như vậy --brief. -briefđược hiểu là -b -r -i -e -f, nói cách khác là một tập hợp các cờ không phải là một tùy chọn duy nhất.
daboross

2
@daboross: wow, tôi đã sử dụng Unix / Linux trong thời gian dài và tôi chưa bao giờ nhận ra có sự khác biệt giữa '-' và '-'. (Tôi không nghĩ '-' tồn tại khi tôi bắt đầu.) Cảm ơn đã giải thích!
Mike Maxwell

287

Lệnh tôi sử dụng là:

diff -qr dir1/ dir2/

Nó giống hệt như của Mark :) Nhưng câu trả lời của anh ấy làm phiền tôi vì nó sử dụng các loại cờ khác nhau , và nó khiến tôi nhìn hai lần. Sử dụng các cờ dài hơn của Mark, đó sẽ là:

diff  --brief --recursive dir1/ dir2/

Tôi xin lỗi vì đã đăng bài khi câu trả lời khác là hoàn toàn chấp nhận được. Không thể dừng bản thân mình ... làm việc để trở nên ít phạm vi hơn.


3
hoàn toàn đánh giá cao sự nhất quán - nhưng đừng cảm thấy tồi tệ; Tôi cũng đánh giá cao câu trả lời của Mark;)
Gerard ONeill 9/03/2015

10
.. nó có ý nghĩa tu đặt câu trả lời khác nhau với CHỈ một hương vị khác nhau? IMHO không! Liệu nó có ý nghĩa tu kết hợp cả hai câu trả lời cho một câu trả lời nhất quán? Đúng! ;)
sobi3ch

1
Chỉ là một câu hỏi; những gì hiện qđứng cho? Nó có phải là viết tắt của một cái gì đó? Tôi không thể tìm thấy bất kỳ logic nào đằng sau q..
kramer65

3
@ kramer65 - nó giống như "--brief", nhưng tôi đoán bạn tự hỏi tại sao q? Có lẽ cho nhanh? "-B" được thực hiện bằng cách "bỏ qua những thay đổi về lượng khoảng trắng" theo trang nam.
FPC

4
@ kramer65 Tôi tin qlà vì quiet, nói chung có nghĩa là ít dài dòng hơn.
Gogeta70

105

Tôi thích sử dụng git diff --no-index dir1/ dir2/, bởi vì nó có thể hiển thị sự khác biệt về màu sắc (nếu bạn có tùy chọn đó được đặt trong cấu hình git của bạn) và vì nó hiển thị tất cả các khác biệt trong một đầu ra phân trang dài bằng cách sử dụng "ít".


25
Khéo léo. Ai có thể đoán rằng git có thể khác các thư mục tùy ý, không chỉ là repo đối với các tệp của nó?
Dan Dascalescu

2
Perl script colordiff rất hữu ích ở đây, có thể được sử dụng với svn và diff khác.
Felipe Alvarez

4
Nếu bạn so sánh (như tôi) 2 dirs như các dự án / repos riêng biệt thì bạn cần thêm --no-indexnhiều hơn vào stackoverflow.com/a/1792477/473390 . Tôi đã cập nhật câu trả lời @ alan-porter.
sobi3ch

Tôi thích cái này, tôi cũng thấy rằng nếu bạn thêm --name-status vào dòng lệnh, nó sẽ chỉ hiển thị danh sách tên tệp với cờ "M / A / D" cho trạng thái Sửa đổi / Đã thêm / Đã xóa.
gzh

Nó xảy ra để cả hai thư mục thực sự chứa thư mục .git, làm thế nào tôi có thể loại trừ nó khỏi so sánh?
Muhamed Cicak

35

Hai lệnh này về cơ bản là điều được yêu cầu:

diff --brief --recursive --no-dereference --new-file --no-ignore-file-name-case /dir1 /dir2 > dirdiff_1.txt

rsync --recursive --delete --links --checksum --verbose --dry-run /dir1/ /dir2/ > dirdiff_2.txt

Sự lựa chọn giữa chúng phụ thuộc vào vị trí của dir1 và dir2:

Khi các thư mục nằm trên hai ổ đĩa riêng biệt, diff vượt trội hơn rsync. Nhưng khi hai thư mục được so sánh nằm trên cùng một ổ đĩa, rsync sẽ nhanh hơn. Đó là bởi vì diff đặt tải gần như bằng nhau cho cả hai thư mục song song, tối đa hóa tải trên hai ổ đĩa.

rsync tính toán tổng trong các khối lớn trước khi thực sự so sánh chúng. Điều đó nhóm các hoạt động i / o theo khối lớn và dẫn đến xử lý hiệu quả hơn khi mọi thứ diễn ra trên một ổ đĩa.


3
rsync không chỉ nhanh hơn cho các tệp trên các ổ đĩa đơn, mà còn cho phép so sánh các tệp trong các thư mục con, ví dụ, rsync --options /usr /bin /var /sbin /lib /old_rootsẽ so sánh hiệu quả gốc hiện tại /(bằng cách chỉ định tất cả các thư mục con trong đó) và /old_root(ví dụ như một số bản sao lưu cũ hơn /), đó là thứ diff -rcó thể không làm Và nếu bạn cho rằng các tệp có cùng kích thước, quyền và dấu thời gian có thể không thay đổi, việc bỏ đi --checksumsẽ cung cấp cho bạn kiểm tra cực kỳ nhanh (nếu không thông qua) xem tệp nào có thể đã thay đổi.
Matija Nalis

1
Mục đích của --deletevới là rsyncgì?
Tom Hale

2
Mục đích của --delete là xóa các tệp hiện có trong đích-dir không còn (hiện tại nữa) trong nguồn-dir
Thomas Munk

2
Trong trường hợp này (với --dry-runcờ), không có gì thực sự bị xóa, rsyncchỉ in những tệp nào trong dir1 chứ không phải trong dir2
mata

11
Tôi khuyên bạn nên đặt --dry-runđầu tiên luôn để không vô tình quên nó.
Dave Rager

22

Meld cũng là một công cụ tuyệt vời để so sánh hai thư mục:

meld dir1/ dir2/

Meld có nhiều tùy chọn để so sánh các tập tin hoặc thư mục. Nếu hai tệp khác nhau, thật dễ dàng để vào chế độ so sánh tệp và xem sự khác biệt chính xác.


2
Đẹp. Tôi đã viết một kịch bản perl đơn giản để thực hiện so sánh trên cây nhưng tôi đang gặp phải những hạn chế. Đây dường như là vé.
David Tonhofer

Vấn đề duy nhất là nó không cho vay kịch bản vì nó là một ứng dụng đồ họa. Nhưng thật tuyệt nếu bạn không quan tâm đến GUI! Cảm ơn.
DeanM

Tôi thấy rằng nó meldtrở nên chậm chạp khủng khiếp nếu được sử dụng trên các thư mục lớn mặc dù. Có bất cứ điều gì xử lý các thư mục lớn tốt hơn?
Popup

@Popup, không phải tôi biết. Mặc dù vậy, bạn có thể tìm thấy các tên tệp khác nhau với một cái gì đó như thế này:find dir1 dir2 | cut -d/ -f2- | sort | uniq --unique
Alexander

1
@Alexander - Trong trường hợp đó tôi thấy nó meld <(find dir1 -ls ) <(find dir2 -ls)hoạt động khá tốt, sử dụng thay thế quá trình bash. (zsh's =(command)hoạt động thậm chí còn tốt hơn.)
Popup

10

Người đồng hương 'billings' (của freenode / # centos fame) đã chia sẻ phương pháp của anh ấy với tôi:

diff -Naur dir1/ dir2

Bao gồm cả thư mục cuối cùng dấu gạch chéo không thành vấn đề.

Ngoài ra, nó xuất hiện -u tùy chọn không có sẵn trên một số phiên bản máy chủ / máy chủ cũ hơn.

Sự khác biệt trong khác biệt:

# diff -Nar /tmp/dir1 /tmp/dir2/
diff -Nar /tmp/dir1/file /tmp/dir2/file
28a29
> TEST

# diff -qr /tmp/dir1/ /tmp/dir2/
Files /tmp/dir1/file and /tmp/dir2/file differ

2
Vì vậy, điều --new-file/-Nđó làm cho diff coi các tệp bị thiếu là trống và --text/-ađiều đó khiến nó coi tất cả đầu vào nhị phân là văn bản. Tôi không thấy những mặt tích cực cho trường hợp sử dụng cụ thể này.
phk

4

Máy soi là một công cụ tìm thư mục dựa trên dòng lệnh tuyệt vời.

Tôi đặc biệt thích về nó rằng nó có thể khác thành tập tin:

Nó sẽ giải nén đệ quy các tài liệu lưu trữ thuộc nhiều loại và biến đổi các định dạng nhị phân khác nhau thành dạng dễ đọc hơn để so sánh chúng. Nó có thể so sánh hai tarball, hình ảnh ISO hoặc PDF một cách dễ dàng.

Nó sẽ không chỉ cho bạn biết các tập tin khác nhau, mà còn khác nhau như thế nào.


4

Để tìm diff sử dụng lệnh này:

diff -qr dir1/ dir2/

-r sẽ khác tất cả các thư mục con quá -q chỉ báo cho diff chỉ báo cáo khi các tệp khác nhau.

diff  --brief dir1/ dir2/

--brief sẽ hiển thị các tệp mà dosent tồn tại trong thư mục.

Hoặc cái gì đó khác

chúng ta có thể sử dụng Meld sẽ hiển thị trong cửa sổ đồ họa để dễ dàng tìm thấy sự khác biệt.

meld  dir1/ dir2/

2
--brief-qlà cùng một lựa chọn. Tuyên bố của bạn làm cho nó có vẻ như họ khác nhau nhưng họ không.
Elijah Lynn

2

Bạn cũng có thể sử dụng Rsyncfind. Dành cho find:

find $FOLDER -type f | cut -d/ -f2- | sort > /tmp/file_list_$FOLDER

Nhưng các tệp có cùng tên và trong cùng một thư mục con, nhưng có nội dung khác nhau, sẽ không được hiển thị trong danh sách.

Nếu bạn là người hâm mộ GUI, bạn có thể kiểm tra Meld@Alexander đã đề cập. Nó hoạt động tốt trong cả windows và linux.


1

Để báo cáo sự khác biệt giữa dirA và dirB, đồng thời cập nhật / đồng bộ hóa.

rsync -auv <dirA> <dirB>

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.