Bagaimana saya bisa membuat 'diff -X' mengabaikan jalur tertentu dan bukan mengajukan nama?

29

Perbuatan: diff -r -X <ignore-list> <src-dir> <dest-dir>

tampaknya tidak membuat diffentri abaikan <ignore-list>jika isinya berupa <dir>/<file>.

Entri dari formulir <file> bagaimanapun dipertimbangkan. Ini adalah masalah karena saya mungkin memiliki beberapa file yang dinamai <file>dalam sub-direktori yang berbeda, beberapa di antaranya saya tidak ingin diabaikan.

Sepertinya tidak ada banyak informasi mengenai sintaksis pola di manual untuk diffkeduanya. Dari apa yang saya tahu, itu hanya nama-dasar dari sebuah file yang dianggap oleh diff (lihat http://forums.gentoo.org/viewtopic-t-889788-start-0.html jika Anda tertarik).

Abu
sumber
man, diff's --excludepilihan begitu menyebalkan ...
Elouan Keryell-Bahkan

Jawaban:

30

Direktori listing harus berfungsi; misalnya, inilah yang saya gunakan dalam sebuah skrip (dengan asumsi gnu diff),

diff -r \
   --exclude="*~" \
   --exclude=".svn" \
   --exclude=".git" \
   --exclude="*.zip*" \
   --exclude="*.gz" \
   --exclude="*.tar" \
   ...etc

... yang mengabaikan isi .svndan .gitdirektori, tetapi juga file individual bernama *.zip/ *.gz/ etc.

Sunting: Untuk memfilter jalur formulir dir_a/file1tetapi masih diffmenggunakan nama file yang sama, seperti dir_b/file1atau dir_a/b/file1, maka daftar file yang diffharus dihasilkan (misalnya, menggunakan find), dan file untuk membandingkan berasal dari jalur ini; mis. diberikan

$ find ONE TWO -type f -print 
ONE/a/1.txt
ONE/a/2.txt
ONE/a/b/2.txt
TWO/a/1.txt
TWO/a/2.txt
TWO/a/b/2.txt

Anda menghasilkan daftar file untuk dibandingkan, tidak termasuk misalnya */a/2.txttetapi masih membandingkan file lain bernama 2.txt. Cukup "cari" semua file kecuali ONE/a/2.txt(regexp juga dapat digunakan di sini, seperti .*/a/2.txt)

$ find ONE -type f \( ! -regex 'ONE/a/2.txt' \) \
    -exec bash -c 'diff -q "${1}" "${2/ONE/TWO}"' - {} {} \;  

yang berlaku mengabaikan ONE/a/2.txt(dan TWO/a/2.txt), tetapi masih membandingkan file lain bernama 2.txt:

diff -q ONE/a/1.txt TWO/a/1.txt
diff -q ONE/a/b/2.txt TWO/a/b/2.txt

Sunting: Atau, lebih banyak kesenangan dengan find(kesenangan tambahan tersisa sebagai latihan untuk pembaca), pilih file atau direktori yang akan dikecualikan dan kemudian yang difflainnya:

$ find ONE \( -regex 'ONE/a/2.txt' -o -name b  -prune \)  \
    -o -type f -exec bash -c 'echo diff -q "${1}" "${2/ONE/TWO}"' - {} {} \

Contoh di atas tidak termasuk file spesifik "{top} /a/2.txt", direktori apa pun yang bernama "b", dan yang lainnya berbeda. (Alih-alih sederhana " -name b" Anda juga bisa menggunakan " -regex '.*/b'" - note, no trailing "/".)

michael
sumber
2
Terima kasih tapi saya pikir Anda tidak mengerti intinya. Satu-satunya dukungan yang tampaknya ada adalah ketika Anda menggunakan 'nama-dasar'. Itu bisa berupa nama direktori atau file. Dalam kedua kasus tersebut, diff mengabaikan apa yang Anda minta. Masalah muncul ketika Anda menggunakan jalur. Misalnya, saya tidak bisa mendapatkan diff untuk mengabaikan / an / absolute / path / ke / file / atau ./a/relative/path/to/a/file.
Ash
2
diff --exclude = "/ this / specific / file / that / im / secara eksplisit / memohon / Anda / untuk / abaikan". Itu tidak akan berhasil.
Ash
3
benar, excludepola dicocokkan dengan nama file file (sesuai gnu.org/software/diffutils/manual/html_node/… ); jalur tidak akan berfungsi (seperti pada foo/bar.txt). Untuk melakukan itu, Anda mungkin harus menjalankan finduntuk menghasilkan daftar nama file, dan mendapatkan path ke file untuk membandingkan.
michael
jawaban yang diperbarui untuk menyertakan contoh tidak termasuk jalur file dari diff, bukan hanya menggunakanbasename
michael
Oke, saya melihat apa yang Anda usulkan tetapi tampaknya ada masalah. Saya perlu mempertimbangkan direktori juga, bukan hanya file (yaitu -type f). Sekarang, sementara Anda masih dapat memangkas file tertentu menggunakan regexp dengan find, jika input untuk diffberisi direktori, itu akan melalui dan membandingkan file dalam direktori itu dan beberapa file ini mungkin perlu diabaikan .... jadi Anda kembali ke titik 1.
Ash
2

Saya memiliki masalah yang sama jadi saya membuat tambalan untuk diff. Patch belum diterima, tetapi Anda dapat membangun versi Anda sendiri diffdengan patch atau menginstal di Arch Linux dengan paket AUR .

Berikut adalah diffpatch yang.

Dave Parrish
sumber
1

Untuk mengecualikan direktori directory/sub-directory, saya menggunakan

diff -r <src-dir> <dest-dir> | grep -v directory/sub-directory

Namun, meskipun harus bekerja untuk satu pengecualian, itu tidak mungkin untuk daftar abaikan lama seperti yang Anda miliki.

Elouan Keryell-Even
sumber
-2
$ diff -rq foo.orig foo | grep -vP 'ignore1/|exclude2/' | awk '{print $2}' | cut -d'/' -f2- | xargs -I{} diff -u foo.orig/{} foo/{}
vern
sumber
1
Meskipun ini mungkin menjawab pertanyaan, itu akan menjadi jawaban yang lebih baik jika Anda bisa memberikan penjelasan mengapa itu bisa terjadi.
DavidPostill