diff -r สำหรับไฟล์บางประเภทเท่านั้น


12

มีวิธีที่ฉันสามารถทำซ้ำที่แตกต่างกันของสองไดเรกทอรี แต่เปรียบเทียบไฟล์ (ในสถานที่นั้น ๆ ) ที่ตรงกับชื่อไฟล์ที่เฉพาะเจาะจงหรือคำกริยา filetype?

เช่นฉันต้องการทำบางสิ่งเช่น

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

... หรือดีกว่า:

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

เห็นได้ชัดว่ามันไม่ได้บังคับให้ใช้diffเพราะฉันคิดว่าคาถาด้วยfindและ-exec diffอาจทำเคล็ดลับ (ฉันเพิ่งไม่รู้วิธีการสร้าง filepaths เสริมในกรณีหลัง)


3
มีตัวเลือกให้ยกเว้นไฟล์ที่ตรงกับรูปแบบฉันไม่เห็นตัวเลือกให้รวมเฉพาะไฟล์ที่ตรงกับรูปแบบ
Barmar

1
ตัวเลือกทั้งหมดสำหรับการเปรียบเทียบไดเรกทอรีสามารถดูได้ที่gnu.org/software/diffutils/manual/html_node/…
Barmar

1
ดูลิงค์นี้และดูคำตอบSérgio
yehudahs

คำตอบ:


1

Shellscript differ-r

shellscript นี้สามารถดำเนินการแบบเรียกซ้ำของสองไดเรกทอรี แต่จะเปรียบเทียบไฟล์ (ในตำแหน่งที่เกี่ยวข้อง) ที่ตรงกับชื่อไฟล์หรือรูปแบบไฟล์เฉพาะ

#!/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 {} +

การสาธิต

ไฟล์:

$ 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

การใช้งาน:

$ ./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"

วิ่งdiffer-r:

diffบรรทัดคำสั่งที่ดำเนินการจะถูกพิมพ์ด้วยข้อความสีเขียวและผลลัพธ์เมื่อไม่มีการจับคู่ที่ถูกพิมพ์ด้วยข้อความเริ่มต้น (สีขาวบนพื้นดำในภาพหน้าจอต่อไปนี้)

ป้อนคำอธิบายรูปภาพที่นี่

$ ./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 ด้วยตัวกรอง

หากคุณไม่ต้องการรับเอาต์พุตใด ๆ ที่อธิบายถึงความแตกต่างเพียงรู้ว่าไฟล์ใดแตกต่างหรือหายไป (เพื่อที่rsyncจะคัดลอกไฟล์เหล่านั้น) คุณสามารถใช้บรรทัดคำสั่งต่อไปนี้

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

การสาธิต

$ 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)

หากคุณต้องการเอาต์พุตแบบคลีนโดยไม่ต้องแสดงความคิดเห็นบรรทัดและไม่มีไดเรกทอรีคุณสามารถgrepส่งออกเช่นนั้น

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

Shellscript rsync-diff

นี้หนึ่งซับสามารถทำให้เป็นคำสั่งหลักของ rsync-diffshellscript

#!/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

เนื่องจากคุณพูดถึง "ชัดเจนว่าไม่จำเป็นต้องใช้ diff"

นี้ควรจะทำงานให้คุณmeld กำหนดได้ง่ายสำหรับสิ่งที่ชนิดของประเภทไฟล์ที่จะไม่สนใจ:

ป้อนคำอธิบายรูปภาพที่นี่

อีกทางเลือกหนึ่งคือการเขียนสคริปต์ง่าย ๆ ซึ่งจะถ่ายโอนจากรายการขาวไปยังบัญชีดำและหลังจากนั้นบัญชีดำจะถูกส่งผ่านไปยัง diff ด้วย--excludeตัวเลือก


อัปเดตแท็กเพื่อเพิ่ม 'command-line'
Marcus Junius Brutus

0

ด้วยการทดแทนคำสั่งเชลล์ที่สนับสนุนคุณสามารถใช้หนึ่งซับในต่อไปนี้ (ตามที่ระบุไว้แล้วโดย @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:' \
)

มันทำงานได้เช่นนี้: findค้นหาไฟล์ที่ไม่สนใจsedแยกไฟล์เบส (การรันbasenameช้ามากถ้าคุณมีไฟล์จำนวนมาก) และวางไว้ในไฟล์ชั่วคราว ไฟล์ดังกล่าวจะถูกส่งผ่านไปเพื่อdiffบอกให้แยกออกจากการเปรียบเทียบ (double exclusion = inclusion)

หากคุณไม่ได้มีคำสั่งเปลี่ยนตัวใส่ผลลัพธ์ในไฟล์และชัดเจนผ่านไปseddiff

ในตัวอย่างฉันค้นหาเฉพาะไฟล์ XML และ JAVA ให้เปลี่ยนตามที่ต้องการโดยแยกพวกเขาด้วย OR

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.