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


88

J'ai une question sur la commande diff si je veux un répertoire diff récursif mais uniquement pour un type de fichier spécifique, comment faire?

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

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

avec la commande , je ne peux exclure le type de fichier xml, même si il y a des fichiers dans le type d'image de dossier ( png, gif, jpg), txt, php, etc.

comment différencier uniquement certains types de fichiers.



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

Réponses:


97

Vous pouvez spécifier -xplusieurs fois.

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

Dans la section Comparaison des répertoires 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 les noms de base correspondent au modèle de shell PATTERN. Contrairement au shell, un point au début de la base d'un nom de fichier correspond à un caractère générique au début d'un modèle. Vous devez mettre PATTERN entre guillemets afin que le shell ne le développe 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 plus d'une 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'.


Le mien (ubuntu 10.04) n'a pas ces lignes. J'ai aussi essayé et cela n'a pas fonctionné. Je suppose que c'est une nouvelle version.
alumi

22

Tiré de (une version de) la page de manuel:

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

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

Il semble -xdonc n'accepter qu'un seul modèle lorsque vous signalez, mais si vous mettez tous les modèles que vous souhaitez exclure dans un fichier (vraisemblablement un par ligne), vous pouvez utiliser le deuxième indicateur comme ceci:

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

où exclude.pats est:

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

4
Vous pouvez trouver toutes les extensions de fichier dans votre dossier, à l'exception de l'extension <my-ext> avec la ligne de commande suivante: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

J'aurais aimé remarquer le commentaire de John plus tôt, mais sur macOs / bash, je suis venu à une solution similaire pour produire le fichier d'exclusion avec plusieurs modèles à 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-FILEje veux croire que cela aide, peut-être sous Linux aussi. (Dans cet exemple, un single -name "*.[ch]"est correct, mais ce n'est pas très illustratif)
éruption

16

Vous pouvez également utiliser find avec -exec pour appeler diff:

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

7

L'absence de complément - inclure ...

Nous pouvons faire une solution de contournement, un fichier d'exclusion avec tous les fichiers mais ce que nous voulons inclure. Nous créons donc file1avec un find tous les fichiers qui n'ont pas d'extensions que nous voulons inclure, sedattrapons le nom de fichier et c'est juste:

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

Par exemple:

find  PATH1/ -type f | grep --text -vP "php$|html$" | sed 's/.*\///' | sort -u > file1 
diff PATH1/ PATH2/ -rq -X file1 

Une doublure super utile, merci. Sur Mac OSX, grep est légèrement différent et il devient find PATH1/ -type f | grep --text -v -e "php$" -e html$" | sed 's/.*\///' | sort -u > file1 diff PATH1/ PATH2/ -rq -X file1
mmacvicar

3

J'ai utilisé la commande suivante pour trouver le diff de tous les *.tmplfichiers entre DIR1et DIR2. Dans mon cas, cela n'a donné aucun faux positif, mais cela peut pour vous, en fonction du contenu de votre DIRS.

diff --brief DIR1 DIR2 | grep tmpl


2

Si vous le trouvez pratique, vous pouvez utiliser ce qui suit Makefile. Exécutez simplement: "make patch"

#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

1

L'absence d'un -include complémentaire rend nécessaire l'utilisation de modèles heuristiques alambiqués tels que

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

pour trouver (principalement) des fichiers java!


1

Si vous souhaitez différer les sources et rester simple:

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

Supprimez le dernier grep si vous souhaitez récupérer les fichiers qui n'existent que dans l'un des chemins.


0

Bien que cela n'évite pas la réalité diffd'autres fichiers, si votre objectif est de produire un fichier de correctif, ou similaire, vous pouvez utiliser à filterdiffpartir du patchutilspackage, par exemple pour ne corriger que vos .pymodifications:

diff -ruNp /path/1 /path/2 | filterdiff -i "*.py" | tee /path/to/file.patch
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.