diff -r chỉ cho một số loại tệp nhất định


12

Có cách nào để tôi có thể thực hiện một đệ quy khác biệt của hai thư mục nhưng chỉ so sánh các tệp (ở vị trí tương ứng của chúng) khớp với một tên tệp hoặc vị từ filetype cụ thể không?

Ví dụ, tôi muốn làm một cái gì đó như

diff -r dir-a dir-b -filenames *.java, ivy.xml, build.xml

... hoặc thậm chí tốt hơn:

diff -r dir-a dir-b -filetype text

Rõ ràng không bắt buộc phải sử dụng diffvì tôi cho rằng một câu thần chú find-exec diffcũng có thể thực hiện mánh khóe (tôi chỉ không biết cách tạo ra các filepath bổ sung trong trường hợp sau).


3
Có một tùy chọn để loại trừ các tệp khớp với mẫu, tôi không thấy tùy chọn chỉ bao gồm các tệp khớp với mẫu đó.
Barmar

1
Tất cả các tùy chọn cụ thể để so sánh các thư mục có thể được tìm thấy tại gnu.org/software/diffutils/manual/html_node/ Kẻ
Barmar

1
xem liên kết này và xem câu trả lời của Sérgio.
yehudahs

Câu trả lời:


1

Vỏ sò differ-r

Shellscript này có thể thực hiện một đệ quy khác biệt của hai thư mục nhưng chỉ so sánh các tệp (ở vị trí tương ứng của chúng) khớp với một tên tệp hoặc mẫu filetype cụ thể.

#!/bin/bash

greenvid="\0033[32m"
resetvid="\0033[0m"

if [ $# -ne 3 ]
then
 echo "Usage: compare files in two directories including subdirectories"
 echo "         $0 <source-dir> <target-dir> <pattern>"
 echo "Example: $0  subdir-1     subdir-2     \"*.txt\""
 exit
fi

cmd='for pathname do
        greenvid="\0033[32m"
        resetvid="\0033[0m"
        echo -e "${greenvid}diff \"$pathname\" \"${pathname/'\"$1\"'/'\"$2\"'}\"${resetvid}"
        diff "$pathname" "${pathname/'\"$1\"'/'\"$2\"'}"
    done'
#echo "$cmd"

find "$1" -type f -name "$3" -exec bash -c "$cmd" bash {} +

Bản giới thiệu

Các tập tin:

$ find -type f
./1/ett.txt
./1/two.doc
./1/t r e.txt
./1/sub/only-one.doc
./1/sub/hello.doc
./1/sub/hejsan.doc
./differ-r2
./differ-r1
./differ-r
./2/ett.txt
./2/two.doc
./2/t r e.txt
./2/sub/hello.doc
./2/sub/hejsan.doc

Sử dụng:

$ ./differ-r
Usage: compare files in two directories including subdirectories
         ./differ-r <source-dir> <target-dir> <pattern>
Example: ./differ-r  subdir-1     subdir-2     "*.txt"

Chạy differ-r:

Các diffdòng lệnh được thực hiện được in bằng văn bản màu xanh lá cây và đầu ra, khi không có kết quả khớp với văn bản mặc định (màu trắng trên nền đen trong ảnh chụp màn hình sau).

nhập mô tả hình ảnh ở đây

$ ./differ-r 1 2 "*.doc"
diff "1/two.doc" "2/two.doc"
diff "1/sub/only-one.doc" "2/sub/only-one.doc"
diff: 2/sub/only-one.doc: No such file or directory
diff "1/sub/hello.doc" "2/sub/hello.doc"
2d1
< world
diff "1/sub/hejsan.doc" "2/sub/hejsan.doc"

$ ./differ-r 1 2 "*.txt"
diff "1/ett.txt" "2/ett.txt"
2c2
< stabben
---
> farsan
diff "1/t r e.txt" "2/t r e.txt"
1c1
< t r e
---
> 3
$ 

$ ./differ-r 1 2 "*"
diff "1/ett.txt" "2/ett.txt"
2c2
< stabben
---
> farsan
diff "1/two.doc" "2/two.doc"
diff "1/t r e.txt" "2/t r e.txt"
1c1
< t r e
---
> 3
diff "1/sub/only-one.doc" "2/sub/only-one.doc"
diff: 2/sub/only-one.doc: No such file or directory
diff "1/sub/hello.doc" "2/sub/hello.doc"
2d1
< world
diff "1/sub/hejsan.doc" "2/sub/hejsan.doc"

$ ./differ-r 2 1 "*"
diff "2/ett.txt" "1/ett.txt"
2c2
< farsan
---
> stabben
diff "2/two.doc" "1/two.doc"
diff "2/t r e.txt" "1/t r e.txt"
1c1
< 3
---
> t r e
diff "2/sub/hello.doc" "1/sub/hello.doc"
1a2
> world
diff "2/sub/hejsan.doc" "1/sub/hejsan.doc"

rsync với bộ lọc

Nếu bạn không cần nhận bất kỳ đầu ra nào mô tả sự khác biệt, chỉ cần biết tệp nào khác hoặc thiếu (vì vậy rsyncmuốn sao chép chúng), bạn có thể sử dụng dòng lệnh sau.

rsync --filter="+ <pattern>" --filter="+ */" --filter="- *"--filter="- */"  -avcn <source directory>/ <target directory>

Bản giới thiệu

$ rsync --filter="+ *.doc" --filter="+ */" --filter="- *"  -avcn 1/ 2
sending incremental file list
./
sub/
sub/hello.doc
sub/only-one.doc

sent 276 bytes  received 35 bytes  622.00 bytes/sec
total size is 40  speedup is 0.13 (DRY RUN)

sent 360 bytes  received 41 bytes  802.00 bytes/sec
total size is 61  speedup is 0.15 (DRY RUN)
olle@bionic64 /media/multimed-2/test/test0/temp $ rsync --filter="+ *.txt" --filter="+ */" --filter="- *" -avcn 1/ 2
sending incremental file list
./
ett.txt
t r e.txt
sub/

sent 184 bytes  received 29 bytes  426.00 bytes/sec
total size is 21  speedup is 0.10 (DRY RUN)

Nếu bạn muốn một đầu ra sạch mà không cần bình luận dòng và không có thư mục, bạn có thể grepđầu ra như vậy,

$ pattern="*.doc"; rsync --filter="+ $pattern" --filter="+ */" --filter="- *"  -avcn 1/ 2 | grep "${pattern/\*/.\*}"
sub/hello.doc
sub/only-one.doc

Vỏ sò rsync-diff

Điều này có thể được thực hiện thành lệnh cốt lõi của shellscript rsync-diff.

#!/bin/bash

LANG=C

if [ $# -ne 3 ]
then
 echo "Usage: compare files in two directories including subdirectories"
 echo "         $0 <source-dir> <target-dir> <pattern>"
 echo "Example: $0  subdir-1     subdir-2     \"*.txt\""
 exit
fi

pattern="$3"; rsync --filter="+ $pattern" --filter="+ */" --filter="- *" \
 -avcn "$1"/ "$2" | grep "${pattern//\*/.\*}" | grep -v \
  -e '/$' \
  -e '^sending incremental file list$' \
  -e '^sent.*received.*sec$' \
  -e '^total size is.*speedup.*(DRY RUN)$'

0

Vì bạn đã đề cập "Rõ ràng không bắt buộc phải sử dụng diff",

Điều này sẽ thực hiện công việc cho bạn kết hợp dễ dàng cấu hình cho loại loại tệp nào để bỏ qua:

nhập mô tả hình ảnh ở đây

hơn nữa, một cách khác là viết một tập lệnh đơn giản sẽ chuyển từ danh sách trắng sang danh sách đen và sau đó danh sách đen sẽ được chuyển sang diff với --excludetùy chọn.


các thẻ được cập nhật để thêm 'dòng lệnh'
Marcus Junius Brutus

0

Với shell hỗ trợ thay thế lệnh, bạn có thể sử dụng một lớp lót sau (như đã được ghi chú bởi @JammingThebBits):

diff -r dir-a dir-b --exclude-from=<( \
find dir-a dir-b -type f -not \( -name '*.xml'  -or -name '*.java' \) \
| sed 's:^.*/\([^/]*\)$:\1:' \
)

Nó hoạt động như thế này: findtìm kiếm các tệp không quan tâm, sedtrích xuất tên cơ sở (chạy basenamecực kỳ chậm nếu bạn có nhiều tệp) và đặt chúng vào một tệp tạm thời ; tập tin đó sau đó được chuyển đến để diffbảo nó loại trừ chúng khỏi so sánh (loại trừ kép = bao gồm).

Nếu bạn không có lệnh thay thế, hãy đặt sedđầu ra vào một tệp và chuyển nó một cách rõ ràng diff.

Trong ví dụ tôi chỉ tìm kiếm tệp XML và JAVA, thay đổi chúng khi cần bằng cách tách chúng bằng OR.

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.