web-dev-qa-db-fra.com

Comment différencier plusieurs fichiers sur plusieurs répertoires?

J'essaie de trouver diffs entre tous les fichiers du même nom sur deux copies d'un répertoire (disons un travail et une sauvegarde). Par exemple, je peux diff deux fichiers du même nom dans les deux:

> diff d1/f.cpp d2/f.cpp

ou je peux trouver des différences entre les annuaires:

> diff d1 d2

mais comment puis-je trouver des différences entre les fichiers *.cpp uniquement?

> diff d1/*.cpp d2/*.cpp

ne semble pas fonctionner (pour des raisons évidentes).

[Il est probablement facile de résoudre avec des boucles, mais j'essaie de trouver un moyen plus élégant]

19
ysap

Vous pouvez utiliser une boucle Shell qui exécute diff pour chaque fichier, bien que cela ne puisse pas intercepter les cas où d2 contient un fichier, mais pas d1. Cela pourrait suffire cependant.

for file in d1/*.cpp; do
    diff "$file" "d2/${file##*/}"
done

Ou tout sur une seule ligne:

for file in d1/*.cpp; do diff "$file" "d2/${file##*/}"; done

La partie ${file##*/} est un développement de paramètre spécial.

Si la variable de fichier contient d1/hello.cpp, alors "${file##*/}" sera étendu à hello.cpp (la valeur du fichier, mais avec tout, y compris le dernier/supprimé).

Donc, "d2/${file##*/}" donnera d2/hello.cpp et la commande diff résultante sera donc diff d1/hello.cpp d2/hello.cpp

Voir http://mywiki.wooledge.org/BashFAQ/1 pour plus d'informations sur les manipulations de chaîne dans bash.

Sur une note de côté, un système de contrôle de version (tel que Subversion, git, Mercurial, etc.) faciliterait beaucoup ce type de diffing.

13
geirha

diff -qr {DIR1} {DIR2} fait tous les fichiers dans les deux répertoires.

  • q n'affiche que les différences
  • r fait récursif. Ne le laissez pas si vous n'en avez pas besoin

Vous ne pouvez pas dire à diff directement d'utiliser des caractères génériques, mais vous pouvez ajouter:

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

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

exclure des fichiers. Donc, si vous ne voulez que *.cpp, la méthode la plus simple consiste à créer un fichier texte répertoriant tous les fichiers autres que *.cpp. Vous pouvez le faire avec la commande suivante: ls -I "*.cpp" > excluded_files où l’argument -I "*.cpp" ignore tous les fichiers .cpp. Notez que les guillemets sont nécessaires.

50
Rinzwind

Quelque temps après avoir posé la question, j'ai découvert l'utilitaire meldNAME _ diff, et je l'utilise depuis lors. C’est un excellent programme basé sur une interface graphique qui facilite la comparaison et la fusion de fichiers et de répertoires. Il compare deux ou trois voies.

Plus précisément, il répond à ma question initiale en vous montrant une comparaison codée par couleur du contenu du répertoire et en vous permettant de comparer des fichiers spécifiques en double-cliquant sur le nom du fichier.

Si vous avez besoin de plus d’une comparaison à trois voies, alors gvimdiff(basé sur l’éditeur vimname__) est également un excellent moyen de fournir cette fonctionnalité.

4
ysap

Il existe une solution légère pour cela:

  1. Configurez ce petit plugin http://www.vim.org/scripts/script.php?script_id=5309
  2. Faites diff dir1 dir2 | vim -R - chez Shell

Il ajoutera des replis et une comparaison côte à côte pour les fichiers modifiés.

1
Yuriy Ershov