khác một thư mục đệ quy, bỏ qua tất cả các tệp nhị phân


77

Làm việc trên một hộp Fedora Constantine. Tôi đang tìm kiếm diffhai thư mục đệ quy để kiểm tra các thay đổi nguồn. Do việc thiết lập dự án (trước khi tôi tham gia vào dự án đã nói! Thở dài ), các thư mục chứa cả mã nguồn và tệp nhị phân, cũng như các bộ dữ liệu nhị phân lớn. Mặc dù khác biệt cuối cùng hoạt động trên các thư mục này, có lẽ sẽ mất hai mươi giây nếu tôi có thể bỏ qua các tệp nhị phân.

Theo như tôi hiểu, diff không có chế độ 'bỏ qua tệp nhị phân', nhưng có đối số bỏ qua sẽ bỏ qua biểu thức chính quy trong tệp. Tôi không biết viết gì ở đó để bỏ qua các tệp nhị phân, bất kể phần mở rộng.

Tôi đang sử dụng lệnh sau, nhưng nó không bỏ qua các tệp nhị phân. Có ai biết làm thế nào để sửa đổi lệnh này để làm điều này?

diff -rq dir1 dir2

2
Hãy thử sử dụng cmpthay vì diff, sẽ không bỏ qua các tệp nhị phân, nhưng sẽ nhanh hơn
Fredrik Pihl

2
eek. đây là sự biện minh cho người đăng-con cho việc kiểm soát nguồn. nếu bạn không sử dụng nó, bạn nên sử dụng. nếu quyết định không nằm trong tay bạn, bạn nên tranh luận sôi nổi. vấn đề của bạn sẽ biến mất với một thiết lập git thích hợp ...
sợ hãi đăng

6
Tin tôi đi. Tôi biết. Tôi đang thực hiện nghiên cứu ở bậc đại học và điều này không hoàn toàn được thiết lập theo cách nó phải như vậy. Tin tôi đi. TÔI BIẾT. CVS / SVN / GIT sẽ sửa lỗi này. Biết điều gì tệ hơn thế không? Tôi được chỉ định làm việc trong một dự án Fortran với ít hoặc không có tài liệu. Có 8 phiên bản của dự án trong thư mục này và mỗi phiên bản có các tệp trang điểm khác nhau (gần như;)) làm cùng một thứ. Tin bạn đi, tôi cũng đang tranh cãi với giám thị của mình.
Zéychin

Câu trả lời:


32

Có thể sử dụng grep -I(tương đương với grep --binary-files=without-match) làm bộ lọc để sắp xếp các tệp nhị phân.

dir1='folder-1'
dir2='folder-2'
IFS=$'\n'
for file in $(grep -Ilsr -m 1 '.' "$dir1"); do
   diff -q "$file" "${file/${dir1}/${dir2}}"
done

Điều này có vẻ cực kỳ hứa hẹn. Tôi sẽ kiểm tra điều này và cho bạn biết nó diễn ra như thế nào / chấp nhận như một câu trả lời nếu nó hoạt động!
Zéychin

2
Bất cứ ai biết mục đích của IFS=$'\n'?
Zubin

5
Nó là một biến nội bộ bash. Tìm IFS trong tldp.org/LDP/abs/html/internalvariables.html để biết định nghĩa và hành vi chính xác của nó.
Harsh J

1
@Zubin IFS có nghĩa tách lĩnh vực nội bộ, sử dụng để tạo mảng bằng cách tách chuỗi theo giá trị do IFS
Hãy Wake Pandey


65

Loại gian lận nhưng đây là những gì tôi đã sử dụng:

diff -r dir1/ dir2/ | sed '/Binary\ files\ /d' >outputfile

Điều này so sánh đệ quy dir1 với dir2, sed loại bỏ các dòng cho tệp nhị phân (bắt đầu bằng "Tệp nhị phân"), sau đó nó được chuyển hướng đến tệp đầu ra.


7
@Serg Bạn có thể loại trừ các tệp bằng -xcờ. diff -r -x '*.xml' dir1 dir2Cũng thử , man diffđể biết thêm thông tin.
xdhmoore

1
Nếu bạn đang sử dụng hệ thống với ngôn ngữ khác, hãy thay thế Binary\ files\ bằng từ thích hợp trong ngôn ngữ của bạn. Nó phải là một hoặc hai từ đầu tiên. Bằng tiếng Đức, nóBinärdateien\
kap

1
@xdhmoore Cảm ơn bạn đã nhận xét! Để thêm vào nó, -xcũng có thể lặp lại, nếu bạn muốn loại trừ nhiều mẫu. Một cái gì đó giống như -x '*.ext1' -x '*.ext2' -x 'ext3'.
Vasan

13

Tôi đến với câu hỏi (cũ) này để tìm kiếm thứ gì đó tương tự (Định cấu hình tệp trên máy chủ sản xuất kế thừa so với cài đặt apache mặc định). Làm theo đề xuất của @ Fearlesstost trong các nhận xét, gitđủ nhẹ và nhanh nên có lẽ nó đơn giản hơn bất kỳ đề xuất nào ở trên. Sao chép phiên bản1 vào một thư mục mới. Sau đó làm:

git init
git add .
git commit -m 'Version 1'

Bây giờ xóa tất cả các tệp từ phiên bản 1 trong thư mục này và sao chép phiên bản 2 vào thư mục. Bây giờ làm:

git add .
git commit -m 'Version 2'
git show

Điều này sẽ cho bạn thấy phiên bản của Git về tất cả sự khác biệt giữa cam kết đầu tiên và cam kết thứ hai. Đối với các tệp nhị phân, nó sẽ chỉ nói rằng chúng khác nhau. Ngoài ra, bạn có thể tạo một nhánh cho từng phiên bản và cố gắng hợp nhất chúng bằng các công cụ hợp nhất của git.


5

Nếu tên của các tệp nhị phân trong dự án của bạn tuân theo một mẫu cụ thể ( *.o,, *.so...) như chúng thường làm, bạn có thể đặt các mẫu đó vào một tệp và chỉ định nó bằng cách sử dụng -X(gạch nối X).

Nội dung của tôi exclude_file

*.o
*.so
*.git

Chỉ huy:

diff -X exclude_file -r . other_tree > my_diff_file

CẬP NHẬT:

-xcó thể được sử dụng thay thế -X, để chỉ định các mẫu loại trừ trên dòng lệnh thay vì trong tệp:

diff -r -x *.o -x *.so -x *.git dir1 dir2

1
Nó là -x KHÔNG PHẢI -X.
code_dweller

2
@code_dweller Cả hai đều tồn tại: -xlà để loại trừ một mẫu trên dòng lệnh, đồng thời -Xcho biết tệp chứa tất cả các mẫu sẽ được loại trừ.
simlev

0

Sử dụng một sự kết hợp của findfilelệnh. Điều này yêu cầu bạn thực hiện một số nghiên cứu về đầu ra của filelệnh trong thư mục của bạn; dưới đây, tôi giả định rằng các tệp bạn muốn khác biệt được báo cáo là ascii. HOẶC, sử dụng grep -vđể lọc ra các tệp nhị phân.

#!/bin/bash

dir1=/path/to/first/folder
dir2=/path/to/second/folder

cd $dir1
files=$(find . -type f -print | xargs file | grep ASCII | cut -d: -f1)

for i in $files;
do
    echo diffing $i ---- $dir2/$i
    diff -q $i $dir2/$i
done

Vì bạn có thể biết tên của các tệp nhị phân khổng lồ, hãy đặt chúng trong một mảng băm và chỉ tạo sự khác biệt khi tệp không có trong hàm băm, giống như sau:

#!/bin/bash

dir1=/path/to/first/directory
dir2=/path/to/second/directory

content_dir1=$(mktemp)
content_dir2=$(mktemp)

$(cd $dir1 && find . -type f -print > $content_dir1)
$(cd $dir2 && find . -type f -print > $content_dir2)

echo Files that only exist in one of the paths
echo -----------------------------------------
diff $content_dir1 $content_dir2    

#Files 2 Ignore
declare -A F2I
F2I=( [sqlite3]=1 [binfile2]=1 )

while read f;
do
    b=$(basename $f)
    if ! [[ ${F2I[$b]} ]]; then
        diff $dir1/$f $dir2/$f
    fi
done < $content_dir1

0

Chà, như một kiểu kiểm tra thô thiển, bạn có thể bỏ qua các tệp khớp với / \ 0 /.


1
Vấn đề là nó không giống như diff thậm chí còn hỗ trợ bỏ qua các tệp.
Zéychin

2
Các -xlá cờ có thể được sử dụng để bỏ qua tập tin.
xdhmoore
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.