diff -r yalnızca belirli dosya türleri için


12

İki dizin yinelemeli bir fark gerçekleştirmek ama sadece belirli bir dosya adı veya dosya türü yüklem ile eşleşen dosyaları (kendi yerlerinde) karşılaştırmak bir yolu var mı?

Örneğin şöyle bir şey yapmak istiyorum

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

... hatta daha iyisi:

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

Açıkçası diffbir büyü ile varsayalım olarak kullanmak zorunlu değildir findve -exec diffaynı zamanda hile yapabilir (sadece ikinci durumda tamamlayıcı dosya yollarını nasıl oluşturacağımı bilmiyorum).


3
Bir kalıpla eşleşen dosyaları hariç tutma seçeneği var, yalnızca kalıpla eşleşen dosyaları dahil etme seçeneğini görmüyorum.
Barmar

1
Dizinleri karşılaştırmaya özgü tüm seçenekler gnu.org/software/diffutils/manual/html_node/…
Barmar

1
bu bağlantıya ve Sérgio cevabına bakınız.
yehudahs

Yanıtlar:


1

shellscript differ-r

Bu shellscript iki dizinin özyinelemeli farkını gerçekleştirebilir, ancak yalnızca belirli bir dosya adı veya dosya türü deseniyle eşleşen dosyaları (ilgili yerlerinde) karşılaştırabilir.

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

gösteri

Dosyalar:

$ 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

Kullanımı:

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

Koşu differ-r:

Gerçekleştirilen diffkomut satırları yeşil metinle yazdırılır ve varsayılan metinle eşleşme olmadığında çıktı verilir (aşağıdaki ekran görüntüsünde siyah üzerine beyaz).

resim açıklamasını buraya girin

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

Farkı açıklayan herhangi bir çıktı almanız gerekmiyorsa, yalnızca hangi dosyaların farklı veya eksik olduğunu bilin (bu rsyncşekilde kopyalamak istersiniz), aşağıdaki komut satırını kullanabilirsiniz.

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

gösteri

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

Satırları açıklamadan ve dizinler olmadan temiz bir çıktı istiyorsanız grep, çıktıyı şöyle yapabilirsiniz ,

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

shellscript rsync-diff

Bu tek astar bir kabuk komut dosyasının çekirdek komutuna dönüştürülebilir 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

"Farklý bir ţekilde kullanmak zorunlu deđil" dediğinden,

Eğer bu işi yapmalıyım birleşmek görmezden dosya türleri tür ne için kolayca yapılandırılabilir:

resim açıklamasını buraya girin

ayrıca başka bir alternatif, beyaz listeden kara listeye aktarılacak basit bir komut dosyası yazmak ve daha sonra kara liste --excludeseçeneği ile diff'e aktarılacaktır .


'komut satırı' eklemek için etiket güncellendi
Marcus Junius Brutus

0

Kabuk destekleme komut değiştirme ile aşağıdaki tek astarı kullanabilirsiniz (@JammingThebBits tarafından zaten belirtildiği gibi):

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

Bu şekilde çalışır: ilgisiz finddosyaları arayın, temel adı sedayıklayın ( basenameçok sayıda dosyanız varsa çalışan son derece yavaştır) ve bunları geçici bir dosyaya koyar ; bu tür bir dosya daha sonra diffbunları karşılaştırma dışında bırakmasını söylemeye aktarılır (çift dışlama = dahil etme).

Komut değişikliği yoksa sedçıktıyı bir dosyaya koyun ve açık bir şekilde iletin diff.

Yalnızca XML ve JAVA dosyasını aradığım örnekte, bunları OR ile ayırarak gerektiği gibi değiştirin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.