Làm thế nào để bạn khác biệt một thư mục chỉ dành cho các tệp thuộc một loại cụ thể?


88

Tôi có câu hỏi về lệnh diff nếu tôi muốn có một thư mục đệ quy khác nhưng chỉ dành cho một loại tệp cụ thể, làm thế nào để thực hiện điều đó?

Tôi đã thử sử dụng tùy chọn loại trừ nhưng chỉ có thể sử dụng một mẫu duy nhất:

$ diff /destination/dir/1 /destination/dir/2 -r -x *.xml

với lệnh tôi chỉ có thể loại trừ các loại tập tin xml, mặc dù có những tập tin trong thư mục loại hình ảnh ( png, gif, jpg), txt, php, vv

làm thế nào để chỉ khác một số loại tệp nhất định.



Vì vậy, bạn đang cố gắng khác biệt các tệp thuộc loại cụ thể hoặc để loại trừ những tệp khác nhau? Câu hỏi không tương quan với mô tả ..
def

Câu trả lời:


97

Bạn có thể chỉ định -xnhiều hơn một lần.

diff -x '*.foo' -x '*.bar' -x '*.baz' /destination/dir/1 /destination/dir/2

Từ phần So sánh Thư mục của info diff(trên hệ thống của tôi, tôi phải làm info -f /usr/share/info/diff.info.gz):

Để bỏ qua một số tệp trong khi so sánh các thư mục, hãy sử dụng tùy chọn '-x PATTERN' hoặc '--exclude = PATTERN'. Tùy chọn này bỏ qua bất kỳ tệp hoặc thư mục con nào có tên cơ sở khớp với mẫu shell PATTERN. Không giống như trong shell, một dấu chấm ở đầu phần gốc của tên tệp khớp với ký tự đại diện ở đầu một mẫu. Bạn nên đặt PATTERN trong dấu ngoặc kép để trình bao không mở rộng nó. Ví dụ: tùy chọn -x '*. [Ao]' bỏ qua bất kỳ tệp nào có tên kết thúc bằng '.a' hoặc '.o'.

Tùy chọn này tích lũy nếu bạn chỉ định nó nhiều hơn một lần. Ví dụ: sử dụng các tùy chọn -x 'RCS' -x '*, v' bỏ qua bất kỳ tệp hoặc thư mục con nào có tên cơ sở là 'RCS' hoặc kết thúc bằng ', v'.


Của tôi (ubuntu 10.04) không có những dòng này. Tôi cũng đã thử và nó không hoạt động. Tôi đoán đây là một phiên bản mới.
alumi

22

Lấy từ (một phiên bản của) trang người đàn ông:

-x PAT  --exclude=PAT
  Exclude files that match PAT.

-X FILE    --exclude-from=FILE
  Exclude files that match any pattern in FILE.

Vì vậy, có vẻ như -xchỉ chấp nhận một mẫu khi bạn báo cáo nhưng nếu bạn đặt tất cả các mẫu bạn muốn loại trừ trong một tệp (có lẽ là một mẫu trên mỗi dòng), bạn có thể sử dụng cờ thứ hai như vậy:

$ diff /destination/dir/1 /destination/dir/2 -r -X exclude.pats

trong đólude.pats là:

*.jpg
*.JPG
*.xml
*.XML
*.png
*.gif

4
Bạn có thể tìm thấy tất cả các phần mở rộng tệp trong thư mục của mình ngoại trừ phần mở rộng <my-ext> bằng dòng lệnh sau:find . -type f -not -name '*.<my-ext>' | xargs -I% basename '%' | awk -F . 'NF > 1 { print "*." $NF}; NF == 1 { print $NF }' | sort | uniq > exclude.pats
John

Tôi ước gì mình nhận thấy bình luận của John sớm hơn, nhưng trên macOs / bash, tôi đã đi đến một giải pháp tương tự để tạo tệp loại trừ với một số mẫu cần lưu giữ: find . -not -name "*.c" -and -not -name "*.h" -and -type f -print0 | xargs -0 basename | grep -E '.*\..+' | sed 's/\./\//g' | xargs basename | xargs printf '*.%s\n' | sort | uniq > X-FILETôi muốn tin rằng điều đó có ích, có thể trên cả Linux. (Trong ví dụ này, một đĩa đơn -name "*.[ch]"thì được, nhưng nó không minh họa lắm)
phát hành

16

Bạn cũng có thể sử dụng find với -exec để gọi diff:

cd /destination/dir/1
find . -name *.xml -exec diff {} /destination/dir/2/{} \;

7

Việc thiếu phần bổ sung - bao gồm ....

Chúng tôi có thể thực hiện một cách giải quyết khác, đó là loại trừ tệp với tất cả các tệp nhưng những gì chúng tôi muốn bao gồm. Vì vậy, chúng tôi tạo file1bằng cách tìm tất cả các tệp không có phần mở rộng mà chúng tôi muốn bao gồm, sedbắt tên tệp và chỉ là:

diff --exclude-from=file1  PATH1/ PATH2/

Ví dụ:

find  PATH1/ -type f | grep --text -vP "php$|html$" | sed 's/.*\///' | sort -u > file1 
diff PATH1/ PATH2/ -rq -X file1 

Một lớp lót siêu hữu ích, thx. Trên Mac OSX grep hơi khác một chút và nó trở thành find PATH1/ -type f | grep --text -v -e "php$" -e html$" | sed 's/.*\///' | sort -u > file1 diff PATH1/ PATH2/ -rq -X file1
mmacvicar

3

Tôi đã sử dụng lệnh sau để tìm sự khác biệt của tất cả *.tmplcác tệp giữa DIR1DIR2. Trong trường hợp của tôi, điều này không mang lại bất kỳ kết quả dương tính giả nào, nhưng nó có thể xảy ra với bạn, tùy thuộc vào nội dung của DIRS của bạn.

diff --brief DIR1 DIR2 | grep tmpl


2

Trong trường hợp bạn thấy nó thuận tiện, bạn có thể sử dụng như sau Makefile. Chỉ cần chạy: "tạo bản vá"

#Makefile for patches

#Exlude following file endings
SUFFIX += o
SUFFIX += so
SUFFIX += exe
SUFFIX += pdf
SUFFIX += swp

#Exlude following folders
FOLDER += bin
FOLDER += lib
FOLDER += Image
FOLDER += models

OPTIONS = Naur

patch: 
    rm test.patch
    diff -$(OPTIONS) \
    $(foreach element, $(SUFFIX) , -x '*.$(element)') \
    $(foreach element, $(FOLDER) , -x '$(element)*') \
        org/ new/ > test.patch  

unpatch: 
    rm test.unpatch
    diff -$(OPTIONS) \
    $(foreach element, $(SUFFIX) , -x '*.$(element)') \
    $(foreach element, $(FOLDER) , -x '$(element)*') \
    new/ org/ > test.unpatch

1

Việc thiếu phần bổ sung - bao gồm làm cho việc sử dụng các mô hình kinh nghiệm phức tạp như

*.[A-Zb-ik-uw-z]*

để tìm (hầu hết) các tệp java!


1

Nếu bạn muốn các nguồn khác nhau và giữ cho nó đơn giản:

diff -rqx "*.a" -x "*.o" -x "*.d" ./PATH1 ./PATH2 | grep "\.cpp " | grep "^Files"

Loại bỏ grep cuối cùng nếu bạn muốn lấy các tệp chỉ tồn tại trong một trong các đường dẫn.


0

Trong khi nó không tránh được thực tế diffcủa các tệp khác, nếu mục tiêu của bạn là tạo tệp vá hoặc tương tự thì bạn có thể sử dụng filterdifftừ patchutilsgói, ví dụ: chỉ vá các .pythay đổi của bạn :

diff -ruNp /path/1 /path/2 | filterdiff -i "*.py" | tee /path/to/file.patch
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.