Các tập tin khác nhau có trong hai thư mục khác nhau


303

Tôi có hai thư mục với cùng một danh sách các tập tin. Tôi cần so sánh tất cả các tập tin có trong cả hai thư mục bằng cách sử dụng difflệnh. Có một tùy chọn dòng lệnh đơn giản để làm điều đó hay tôi phải viết một tập lệnh shell để lấy danh sách tập tin và sau đó lặp qua chúng?

Câu trả lời:


422

Bạn có thể sử dụng difflệnh cho điều đó:

diff -bur folder1/ folder2/

Điều này sẽ tạo ra một khác biệt đệ quy mà bỏ qua khoảng trắng, với bối cảnh thống nhất:

  • cờ b có nghĩa là bỏ qua khoảng trắng
  • cờ u có nghĩa là một bối cảnh thống nhất (3 dòng trước và sau)
  • cờ r có nghĩa là đệ quy

9
Bạn có thể có quyền truy cập vào difflệnh bằng cách tải xuống các tiện ích GNU cho Win32 .
Laurent Etiemble

7
Tôi cũng đã thấy rằng tùy chọn --brief là hữu ích; bạn nhận được một danh sách các tập tin đã thay đổi và có thể xử lý chúng một cách riêng biệt
Dariusz

27
Đối với những người khác thắc mắc, -bbỏ qua thay đổi khoảng trắng và -uđưa ra 3 dòng đệm.
rattray

28
Sẽ dễ nhớ lệnh này hơn nếu bạn sử dụng chà thay vì bur tức làdiff -rub folder1/ folder2/
Một sốGuyOnAComputer

11
Tôi tưởng tượng -bursẽ dễ nhớ nếu bạn sống ở vùng khí hậu lạnh.
AlanH

126

Nếu bạn chỉ muốn xem các tệp khác nhau, bạn có thể sử dụng:

diff -qr dir_one dir_two | sort

Tùy chọn "q" sẽ chỉ hiển thị các tệp khác nhau chứ không hiển thị nội dung khác nhau và "sắp xếp" sẽ sắp xếp đầu ra theo thứ tự bảng chữ cái.


1
Nó thật tuyệt! Cũng hoạt động hiệu quả - tức là nếu toàn bộ thư mục con chỉ tồn tại trong một trong các thư mục, nó sẽ dừng lại trong đó và chỉ báo cáo chính thư mục con (không có nội dung kế tiếp). rất đẹp!!
Một cái gì đó

Đây là một bước đầu tiên thực sự tốt: xem những gì, nếu bất cứ điều gì, không khác nhau, và sau đó làm một chi tiết difftrên mỗi cặp các tập tin khác nhau. Cách tiếp cận của một người sẽ rất khác nhau nếu chỉ có một hoặc hai tệp khác nhau so với nếu hàng tá tệp khác nhau. Tôi có thể bị mất đầu ra từ diffing hàng chục tệp cùng một lúc!
jvriesem

Ngoài ra, có thể bao gồm -x PATTERNtrong lệnh để loại trừ một số thư mục con nhất định. Ví dụ: diff -qr repo1 repo2 -x ".git"sẽ so sánh hai thư mục (repo1 và repo2) nhưng sẽ loại trừ các tệp trong thư mục .git của các thư mục tương ứng.
ViFI

20

Diff có một tùy chọn -rcó nghĩa là để làm điều đó.

diff -r dir1 dir2


11

diffkhông thể chỉ so sánh hai tệp, bằng cách sử dụng -rtùy chọn, đi bộ toàn bộ cây thư mục, kiểm tra đệ quy sự khác biệt giữa các thư mục con và tệp xảy ra tại các điểm so sánh trong mỗi cây.

$ man diff

...

-r  --recursive
        Recursively compare any subdirectories found.

...

3

Nếu đó là GNU diff thì bạn chỉ có thể trỏ nó vào hai thư mục và sử dụng tùy chọn -r.

Nếu không, hãy thử sử dụng

for i in $(\ls -d ./dir1/*); do diff ${i} dir2; done

NB Như Dennis đã chỉ ra trong phần bình luận, bạn thực sự không cần phải thực hiện thay thế lệnh trên ls. Tôi đã làm điều này quá lâu đến nỗi tôi làm việc này rất nhiều trong chế độ lái tự động và thay thế lệnh tôi cần để lấy danh sách các tệp để so sánh.

Ngoài ra, tôi quên thêm rằng tôi làm '\ ls' để tạm thời vô hiệu hóa bí danh ls của mình thành GNU ls để tôi mất thông tin định dạng màu từ danh sách được GNU ls trả về.


2
Không cần thiết phải sử dụng ls:for i in ./dir1/*
Tạm dừng cho đến khi có thông báo mới.

1
@Dennis, phím tắt sôi nổi. +1. Tôi đã quá quen với việc thay thế lệnh mặc dù nó tự động và tôi chỉ sử dụng lệnh nào tôi cần, ví dụ như đôi khi tôi đang sử dụng find. Sử dụng ls cũng cho phép tôi chơi với danh sách thư mục nhiều hơn, ví dụ như thời gian đảo ngược dựa trên trình tự mặc định.
Rob Wells

0

Đây là một kịch bản để hiển thị sự khác biệt giữa các tệp trong hai thư mục. Nó hoạt động đệ quy. Thay đổi dir1 và dir2.

(search() { for i in $1/*; do [ -f "$i" ] && (diff "$1/${i##*/}" "$2/${i##*/}" || echo "files: $1/${i##*/}   $2/${i##*/}"); [ -d "$i" ] && search "$1/${i##*/}" "$2/${i##*/}"; done }; search "dir1" "dir2" )

0

Nếu bạn đặc biệt không muốn so sánh nội dung của các tệp và chỉ kiểm tra xem cái nào không có trong cả hai thư mục, bạn có thể so sánh danh sách các tệp, được tạo bởi một lệnh khác.

diff <(find DIR1 -printf '%P\n' | sort) <(find DIR2 -printf '%P\n' | sort) | grep '^[<>]'

-printf '%P\n'nói findkhông đường dẫn đầu ra tiền tố với thư mục gốc.

Tôi cũng đã thêm sortđể đảm bảo thứ tự các tệp sẽ giống nhau trong cả hai cuộc gọi của find.

Các grepcuối cùng loại bỏ thông tin về dòng đầu vào giống hệt nhau.


-4

Thử cái này:

diff -rq /path/to/folder1 /path/to/folder2      

2
Điều này trùng lặp một câu trả lời hiện có và không thêm nội dung mới. Vui lòng không đăng câu trả lời trừ khi bạn thực sự có điều gì đó mới để đóng góp.
Toby Speight
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.