Pliki Diff obecne w dwóch różnych katalogach

303

Mam dwa katalogi z tą samą listą plików. Muszę porównać wszystkie pliki znajdujące się w obu katalogach za pomocą diffpolecenia. Czy jest to prosta opcja wiersza poleceń, czy muszę napisać skrypt powłoki, aby uzyskać listę plików, a następnie iterować przez nie?

Sudar
źródło

Odpowiedzi:

422

Możesz użyć do tego diffpolecenia:

diff -bur folder1/ folder2/

Spowoduje to wygenerowanie rekurencyjnego diff, który ignoruje spacje, z ujednoliconym kontekstem:

  • Flaga b oznacza ignorowanie białych znaków
  • Flaga u oznacza ujednolicony kontekst (3 linie przed i po)
  • Flaga r oznacza rekurencyjny
Laurent Etiemble
źródło
9
Możesz uzyskać dostęp do diffpolecenia, pobierając narzędzia GNU dla Win32 .
Laurent Etiemble
7
Odkryłem również, że - krótka opcja jest przydatna; dostajesz listę zmienionych plików i możesz je przetwarzać osobno
Dariusz
27
Dla innych zastanawia się, -bignoruje zmiany białych znaków i -udaje 3 linie bufora.
rattray
28
Łatwiej jest zapamiętać to polecenie, jeśli używasz rub zamiast bur tj.diff -rub folder1/ folder2/
SomeGuyOnAComputer
11
Wyobrażam sobie, -burże łatwo byłoby zapamiętać, gdybyś mieszkał w zimnym klimacie.
AlanH
126

Jeśli chcesz zobaczyć tylko różne pliki, możesz użyć:

diff -qr dir_one dir_two | sort

Opcja „q” pokaże tylko pliki, które się różnią, ale nie różnią się treścią, a „sort” uporządkuje dane wyjściowe alfabetycznie.

Suresh
źródło
1
To jest wspaniałe! Działa również wydajnie - tzn. Jeśli cały podkatalog istnieje tylko w jednym z katalogów, przestaje się w nim powtarzać i zgłasza tylko sam podkatalog (bez zawartości następcy). bardzo dobrze!!
Coś Coś
To naprawdę dobry pierwszy krok: zobacz, co się różni, a następnie zrób szczegółowe informacje diffna temat każdej pary różnych plików. Podejście byłoby zupełnie inne, gdyby tylko jeden lub dwa pliki różniły się w porównaniu z dziesiątkami plików. Mogłem zgubić dane wyjściowe z jednoczesnego pobrania diffdziesiątek plików!
jvriesem,
Może także zawierać -x PATTERNw poleceniu wykluczenie niektórych podkatalogów. Na przykład diff -qr repo1 repo2 -x ".git"porówna dwa katalogi (repo1 i repo2), ale wykluczy pliki w folderze .git odpowiednich katalogów.
ViFI
20

Diff ma opcję, -rktóra ma właśnie to zrobić.

diff -r dir1 dir2

CodeRain
źródło
11

diffmoże nie tylko porównywać dwa pliki, ale także, korzystając z -ropcji, chodzić po całych drzewach katalogów, rekurencyjnie sprawdzając różnice między podkatalogami i plikami występującymi w porównywalnych punktach w każdym drzewie.

$ man diff

...

-r  --recursive
        Recursively compare any subdirectories found.

...
miku
źródło
3

Jeśli jest to GNU diff, powinieneś być w stanie wskazać go na dwa katalogi i użyć opcji -r.

W przeciwnym razie spróbuj użyć

for i in $(\ls -d ./dir1/*); do diff ${i} dir2; done

Uwaga: Jak zauważył Dennis w sekcji komentarzy, tak naprawdę nie trzeba wykonywać podstawiania poleceń na ls. Robię to od tak dawna, że ​​właściwie robię to na autopilocie i zastępuję polecenie, aby uzyskać listę plików do porównania.

Zapomniałem również dodać, że robię „\ ls”, aby tymczasowo wyłączyć mój alias ls do GNU ls, aby stracić informacje o formatowaniu kolorów z listy zwróconej przez GNU ls.

Rob Wells
źródło
2
Nie trzeba używać ls:for i in ./dir1/*
Wstrzymano do odwołania.
1
@Dennis, funky skrót. +1. Jestem tak przyzwyczajony do zastępowania poleceń, chociaż jest to automatyczne i używam tylko tych poleceń, których potrzebuję, np. Czasami używam find. Użycie ls pozwala mi także na więcej zabawy z listą katalogów, np. Na podstawie czasu do tyłu zamiast domyślnej sekwencji.
Rob Wells,
0

Oto skrypt pokazujący różnice między plikami w dwóch folderach. Działa rekurencyjnie. Zmień katalog 1 i katalog 2.

(search() { for i in $1/*; do [ -f "$i" ] && (diff "$1/${i##*/}" "$2/${i##*/}" || echo "files: $1/${i##*/}   $2/${i##*/}"); [ -d "$i" ] && search "$1/${i##*/}" "$2/${i##*/}"; done }; search "dir1" "dir2" )
Jewgienij Karpow
źródło
0

Jeśli nie chcesz porównywać zawartości plików i sprawdzać tylko, które nie są obecne w obu katalogach, możesz porównać listy plików wygenerowane przez inne polecenie.

diff <(find DIR1 -printf '%P\n' | sort) <(find DIR2 -printf '%P\n' | sort) | grep '^[<>]'

-printf '%P\n'mówi, findaby nie poprzedzać ścieżek wyjściowych katalogiem głównym.

Dodałem również, sortaby upewnić się, że kolejność plików będzie taka sama w obu wywołaniach find.

Na grepkońcu usuwa informacje o identycznych liniach wejściowych.

BEZ NAZWY
źródło
-4

Spróbuj tego:

diff -rq /path/to/folder1 /path/to/folder2      
Sonali Birari
źródło
2
To powiela istniejącą odpowiedź i nie dodaje żadnej nowej treści. Nie publikuj odpowiedzi, chyba że masz coś nowego do dodania.
Toby Speight