Bagaimana Anda membedakan direktori hanya untuk file dengan tipe tertentu?

88

Saya punya pertanyaan tentang perintah diff jika saya ingin diff direktori rekursif tetapi hanya untuk jenis file tertentu, bagaimana melakukannya?

Saya mencoba menggunakan opsi kecualikan tetapi hanya dapat menggunakan satu pola saja:

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

dengan perintah saya hanya bisa mengecualikan jenis file xml, meskipun ada file dalam jenis folder gambar ( png, gif, jpg), txt, php, dll

bagaimana membedakan jenis file tertentu saja.

de_3
sumber
1
stackoverflow.com/q/10131908/2707864
sancho.s ReinstateMonicaCellio
Jadi, apakah Anda mencoba untuk membedakan file dengan tipe tertentu atau untuk mengecualikan file tersebut dari diffing? Pertanyaan tidak berhubungan dengan deskripsi ..
def

Jawaban:

98

Anda dapat menentukan -xlebih dari satu kali.

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

Dari bagian Membandingkan Direktori info diff(di sistem saya, saya harus melakukannyainfo -f /usr/share/info/diff.info.gz ):

Untuk mengabaikan beberapa file saat membandingkan direktori, gunakan opsi '-x PATTERN' atau '--exclude = PATTERN'. Opsi ini mengabaikan file atau subdirektori yang nama dasarnya cocok dengan pola shell PATTERN. Tidak seperti di shell, titik di awal basis nama file cocok dengan karakter pengganti di awal pola. Anda harus mengapit POLA dalam tanda kutip agar shell tidak mengembangkannya. Misalnya, opsi -x '*. [Ao]' mengabaikan file apa pun yang namanya diakhiri dengan '.a' atau '.o'.

Opsi ini terakumulasi jika Anda menentukannya lebih dari sekali. Misalnya, menggunakan opsi -x 'RCS' -x '*, v' mengabaikan file atau subdirektori mana pun yang nama dasarnya adalah 'RCS' atau diakhiri dengan ', v'.

Dennis Williamson
sumber
Tambang (ubuntu 10.04) tidak memiliki baris ini. Saya juga sudah mencoba dan tidak berhasil. Saya rasa ini adalah versi baru.
alumi
22

Diambil dari (versi) halaman manual:

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

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

Jadi sepertinya -xhanya menerima satu pola saat Anda melaporkan tetapi jika Anda meletakkan semua pola yang ingin Anda kecualikan dalam sebuah file (mungkin satu per baris), Anda dapat menggunakan tanda kedua seperti ini:

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

di mana exclude.pats adalah:

*.jpg
*.JPG
*.xml
*.XML
*.png
*.gif
jamesbtate
sumber
4
Anda dapat menemukan semua ekstensi file dalam folder Anda kecuali untuk ekstensi <saya-ext> dengan baris perintah berikut: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
Saya berharap saya memperhatikan komentar John sebelumnya, tetapi di macOs / bash saya menemukan solusi serupa untuk menghasilkan file pengecualian dengan beberapa pola yang harus disimpan: 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-FILESaya ingin percaya itu membantu, mungkin di Linux juga. (Dalam contoh ini satu -name "*.[ch]"tidak apa-apa, tetapi tidak terlalu menggambarkan)
eruve
16

Anda juga dapat menggunakan find with -exec untuk memanggil diff:

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

Kurangnya pelengkap --termasuk ....

Kami dapat melakukan satu solusi, file kecualikan dengan semua file tetapi yang ingin kami sertakan. Jadi kami membuat file1dengan menemukan semua file yang tidak memiliki ekstensi yang ingin kami sertakan, sedmenangkap nama file dan hanya:

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

Sebagai contoh:

find  PATH1/ -type f | grep --text -vP "php$|html$" | sed 's/.*\///' | sort -u > file1 
diff PATH1/ PATH2/ -rq -X file1 
Sérgio
sumber
Satu kalimat yang sangat berguna, terima kasih. Pada Mac OSX grep sedikit berbeda dan menjadi find PATH1/ -type f | grep --text -v -e "php$" -e html$" | sed 's/.*\///' | sort -u > file1 diff PATH1/ PATH2/ -rq -X file1
mmacvicar
3

Saya menggunakan perintah berikut untuk menemukan diff dari semua *.tmplfile antara DIR1dan DIR2. Dalam kasus saya ini tidak menghasilkan positif palsu, tetapi mungkin untuk Anda, tergantung pada konten DIRS Anda.

diff --brief DIR1 DIR2 | grep tmpl

Mikhail Golubitsky
sumber
2

Jika Anda ingin membedakan sumber dan membuatnya tetap sederhana:

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

Hapus grep terakhir jika Anda ingin mendapatkan file yang hanya ada di salah satu jalur.

Alex
sumber
Saya suka kesederhanaan :-) Dalam bahasa Jerman ubah grep "^Files"menjadigrep "^Dateien"
Erich Kuester
2

Jika Anda merasa nyaman, Anda dapat menggunakan yang berikut ini Makefile. Jalankan saja: "buat tambalan"

#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
Rafiz
sumber
1

Kurangnya komplementer --include membuatnya perlu untuk menggunakan pola heuristik yang berbelit-belit seperti

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

untuk menemukan (kebanyakan) file java!

Jerry Miller
sumber
0

Meskipun tidak menghindari difffile lain yang sebenarnya , jika tujuan Anda adalah menghasilkan file patch, atau yang serupa maka Anda dapat menggunakan filterdiffdari patchutilspaket, misalnya untuk hanya menambal .pyperubahan Anda :

diff -ruNp /path/1 /path/2 | filterdiff -i "*.py" | tee /path/to/file.patch
Cez
sumber