114 votes

Comment différencier un répertoire uniquement pour les fichiers d'un type spécifique ?

J'ai une question sur la commande diff. Si je veux faire une différence de répertoires récursive mais seulement pour un type de fichier spécifique, comment puis-je faire ?

J'ai essayé d'utiliser l'option d'exclusion mais je ne peux utiliser qu'un seul motif :

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

Avec cette commande je ne peux exclure que les fichiers de type xml, même s'il y a des fichiers de type image dans le dossier (png, gif, jpg), txt, php, etc

Comment faire une différence uniquement pour certains types de fichiers.

1 votes

1 votes

Alors, essayez-vous de différencier des fichiers d'un type spécifique ou d'exclure ces fichiers de la différenciation? La question ne correspond pas à la description..

131voto

Dennis Williamson Points 105818

Vous pouvez spécifier -x plusieurs fois.

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

Dans la section Comparing Directories de info diff (sur mon système, je dois faire info -f /usr/share/info/diff.info.gz):

Pour ignorer certains fichiers lors de la comparaison de répertoires, utilisez l'option '-x PATTERN' ou '--exclude=PATTERN'. Cette option ignore tous les fichiers ou sous-répertoires dont le nom de base correspond au modèle shell PATTERN. Contrairement au shell, un point au début du nom de base d'un fichier correspond à un joker au début d'un motif. Vous devez encadrer PATTERN entre guillemets afin que le shell ne l'expande pas. Par exemple, l'option -x '*.[ao]' ignore tout fichier dont le nom se termine par '.a' ou '.o'.

Cette option s'accumule si vous la spécifiez plusieurs fois. Par exemple, en utilisant les options -x 'RCS' -x '*,v' ignore tout fichier ou sous-répertoire dont le nom de base est 'RCS' ou se termine par ',v'.

0 votes

La mienne (ubuntu 10.04) n'a pas ces lignes. J'ai également essayé et ça n'a pas fonctionné. Je suppose que c'est une nouvelle version.

27voto

Puddingfox Points 637

Extrait (d'une version) de la page de l'homme :

-x PAT  --exclude=PAT
  Exclure les fichiers qui correspondent à PAT.

-X FILE    --exclude-from=FILE
  Exclure les fichiers qui correspondent à l'un des motifs dans FILE.

Il semble donc que -x n'accepte qu'un seul motif comme vous le rapportez, mais si vous mettez tous les motifs que vous voulez exclure dans un fichier (probablement un par ligne), vous pourriez utiliser le deuxième indicateur de la manière suivante :

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

où exclude.pats est :

*.jpg
*.JPG
*.xml
*.XML
*.png
*.gif

7 votes

Vous pouvez trouver toutes les extensions de fichiers dans votre dossier, à l'exception de l'extension , avec la ligne de commande suivante : find . -type f -not -name '*.' | xargs -I% basename '%' | awk -F . 'NF > 1 { print "*." $NF}; NF == 1 { print $NF }' | sort | uniq > exclude.pats

1 votes

Je souhaite avoir remarqué le commentaire de John plus tôt, mais sur macOs/bash, j'ai trouvé une solution similaire pour produire le fichier d'exclusion avec plusieurs motifs à conserver : 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-FILE Je veux croire que cela aide, peut-être aussi sur Linux. (Dans cet exemple, un seul -name "*.[ch]" est correct, mais ce n'est pas très illustratif)

2voto

Rafiz Points 1

Si vous le trouvez pratique, vous pouvez utiliser le Makefile suivant. Il vous suffit d'exécuter : "make patch"

# Makefile pour les patchs

# Exclure les extensions de fichiers suivantes
SUFFIX += o
SUFFIX += so
SUFFIX += exe
SUFFIX += pdf
SUFFIX += swp

# Exclure les dossiers suivants
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

2voto

Alex Points 376

Si vous voulez différencier les sources et garder les choses simples :

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

Supprimez le dernier grep si vous voulez obtenir les fichiers qui n'existent que dans l'un des chemins.

0 votes

J'aime la simplicité :-) En allemand, changez grep "^Files" en grep "^Dateien"

1voto

Jerry Miller Points 109

Le manque d'un complément --include rend nécessaire l'utilisation de schémas heuristiques aussi complexes que

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

pour trouver (principalement) des fichiers java!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X