Comment puis-je faire en sorte que «diff -X» ignore les chemins spécifiques et non les noms de fichiers?


29

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

ne semble pas faire diffignorer les entrées <ignore-list>si elles sont de la forme <dir>/<file>.

Les entrées du formulaire <file> sont cependant prises en compte. C'est un problème car je pourrais avoir plusieurs fichiers nommés <file>dans différents sous-répertoires, dont certains que je ne veux pas ignorer.

Il ne semble pas y avoir beaucoup d'informations concernant la syntaxe des modèles dans la page de manuel pour les diffdeux. D'après ce que je peux dire, c'est juste le nom de base d'un fichier qui est considéré par diff (voir http://forums.gentoo.org/viewtopic-t-889788-start-0.html si vous êtes intéressé).


l'homme, diffl' --excludeoption est tellement merdique ...
Elouan Keryell-Even

Réponses:


30

La liste des répertoires devrait fonctionner; par exemple, voici ce que j'ai utilisé dans un script (en supposant que gnu diff),

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

... qui ignore le contenu de .svnet .gitdirs, mais aussi les fichiers individuels nommés *.zip/ *.gz/ etc.

Modifier: Afin de filtrer les chemins du formulaire dir_a/file1mais toujours des difffichiers avec le même nom de base, tels que dir_b/file1ou dir_a/b/file1, alors une liste de fichiers à diffgénérer devrait être (par exemple, en utilisant find), et le fichier à comparer dérivé de ces chemins; par exemple, étant donné

$ 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

vous générez la liste des fichiers à comparer, excluant par exemple */a/2.txtmais toujours en comparant les autres fichiers nommés 2.txt. Il suffit de "trouver" tous les fichiers sauf ONE/a/2.txt(une expression rationnelle peut également être utilisée ici, par exemple .*/a/2.txt)

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

qui en effet ignore ONE/a/2.txt(et TWO/a/2.txt), mais compare toujours les autres fichiers nommés 2.txt:

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

Modifier: Ou, plus amusant avec find(plaisir supplémentaire laissé comme exercice pour le lecteur), sélectionnez les fichiers ou répertoires à exclure , puis difftout le reste:

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

L'exemple ci-dessus exclut le fichier spécifique "{top} /a/2.txt", tout répertoire nommé "b" et tout le reste est différent. (Au lieu du simple " -name b", vous pouvez également utiliser " -regex '.*/b'" - note, pas de "/" à la fin.)


2
Merci mais je pense que vous manquez le point. Le seul support qui semble exister est lorsque vous utilisez un «nom de base». Cela pourrait être le nom d'un répertoire ou d'un fichier. Dans les deux cas, diff ignore ce que vous avez demandé. Le problème se pose lorsque vous utilisez des chemins. Par exemple, je n'arrive pas à faire en sorte que diff ignore / un / absolu / chemin / vers / un / fichier ou ./a/relative/path/to/a/file.
Ash

2
diff --exclude = "/ this / specific / file / that / im / explicit / pleading / you / to / ignore". Ça ne marchera pas.
Ash

3
correct, les excludemotifs sont comparés au nom de base des fichiers (selon gnu.org/software/diffutils/manual/html_node/… ); les chemins ne fonctionneront pas (comme dans foo/bar.txt). Pour ce faire, vous devrez probablement exécuter findpour générer la liste des noms de fichiers et dériver le chemin d'accès au fichier à comparer.
michael

mise à jour de la réponse pour inclure un exemple excluant les chemins de fichiers de la diff, au lieu de simplement utiliserbasename
michael

D'accord, je vois ce que vous proposez, mais il semble y avoir un problème. Je dois également prendre en compte les répertoires, pas seulement les fichiers (c'est-à-dire -type f). Maintenant, bien que vous puissiez toujours éliminer certains fichiers à l'aide de regexp avec find, si l'entrée de diffcontient un répertoire, il parcourra et comparera les fichiers dans ce répertoire et certains de ces fichiers devront peut-être être ignorés .... donc vous êtes retour à la case 1.
Ash


1

Pour exclure le répertoire directory/sub-directory, j'utilise

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

Cependant, bien que cela devrait fonctionner pour une seule exclusion, il ne devrait pas être possible pour une longue liste d'ignorer comme vous l'avez.


-2
$ diff -rq foo.orig foo | grep -vP 'ignore1/|exclude2/' | awk '{print $2}' | cut -d'/' -f2- | xargs -I{} diff -u foo.orig/{} foo/{}

1
Bien que cela puisse répondre à la question, ce serait une meilleure réponse si vous pouviez expliquer pourquoi .
DavidPostill
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.