Odpowiedzi:
Ze strony man diff:
-q
Zgłoś tylko, czy pliki się różnią, a nie szczegóły różnic.
-r
Porównując katalogi, rekurencyjnie porównaj wszystkie znalezione podkatalogi.
Przykładowe polecenie:
diff -qr dir1 dir2
Przykładowe dane wyjściowe (zależy od ustawień regionalnych):
$ ls dir1 dir2
dir1:
same-file different only-1
dir2:
same-file different only-2
$ diff -qr dir1 dir2
Files dir1/different and dir2/different differ
Only in dir1: only-1
Only in dir2: only-2
-x PATTERN
w poleceniu wykluczenie niektórych podkatalogów. Na przykład diff -qr repo1 repo2 -x ".git"
porówna dwa katalogi, ale wykluczy ścieżki plików z „.git” w nich.
Możesz także użyć rsync
rsync -rv --size-only --dry-run /my/source/ /my/dest/ > diff.out
--size-only
będzie brakować plików o identycznym rozmiarze, ale różnej zawartości, np. stary / wersja.txt „29a” nowy / wersja.txt „29b” . Zamiast tego użyj: rsync -ric --dry-run old/ new/
gdzie argument „-i” pozwala uzyskać listę plików bezpośrednio przezrsync -ric --dry-run old/ new/ | cut -d" " -f 2
Jeśli chcesz uzyskać listę plików znajdujących się tylko w jednym katalogu, a nie ich podkatalogów i tylko ich nazwy:
diff -q /dir1 /dir2 | grep /dir1 | grep -E "^Only in*" | sed -n 's/[^:]*: //p'
Jeśli chcesz rekurencyjnie wyświetlić listę wszystkich plików i katalogów, które różnią się ich pełnymi ścieżkami:
diff -rq /dir1 /dir2 | grep -E "^Only in /dir1*" | sed -n 's/://p' | awk '{print $3"/"$4}'
W ten sposób możesz zastosować różne polecenia do wszystkich plików.
Na przykład mogę usunąć wszystkie pliki i katalogi znajdujące się w katalogu 1, ale nie w katalogu 2:
diff -rq /dir1 /dir2 | grep -E "^Only in /dir1*" | sed -n 's/://p' | awk '{print $3"/"$4}' xargs -I {} rm -r {}
W moim systemie Linux, aby uzyskać tylko nazwy plików
diff -q /dir1 /dir2|cut -f2 -d' '
audit-0.0.234/audit-data-warehouse-0.0.234/ audit-0.0.235/audit-data-warehouse-0.0.235/
diff -qrN /dir1 /dir2 | cut -f2 -d' '
działa dobrze dla mnie!
Podejście do uruchamiania diff -qr old/ new/
ma jedną poważną wadę: może brakować plików w nowo utworzonych katalogach. Np. W poniższym przykładzie pliku data/pages/playground/playground.txt
nie ma na wyjściu, diff -qr old/ new/
podczas gdy katalog data/pages/playground/
jest (wyszukaj playground.txt w przeglądarce aby szybko porównać). Opublikowałem również następujące rozwiązanie na giełdzie stosów Unix i Linux , ale skopiuję je również tutaj:
Aby utworzyć listę nowych lub zmodyfikowanych plików programowo najlepszym rozwiązaniem, jakie mogłem wymyślić, jest użycie rsync , sort i uniq :
(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq
Pozwól mi wyjaśnić za pomocą tego przykładu: chcemy porównać dwie wersje dokuwiki, aby zobaczyć, które pliki zostały zmienione, a które nowo utworzone.
Ściągamy smoły za pomocą wget i wyodrębniamy je do katalogów old/
inew/
:
wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29d.tgz
wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29.tgz
mkdir old && tar xzf dokuwiki-2014-09-29.tgz -C old --strip-components=1
mkdir new && tar xzf dokuwiki-2014-09-29d.tgz -C new --strip-components=1
Uruchamianie rsync w jedną stronę może spowodować pominięcie nowo utworzonych plików, ponieważ porównanie rsync i diff pokazuje tutaj:
rsync -rcn --out-format="%n" old/ new/
daje następujące dane wyjściowe:
VERSION
doku.php
conf/mime.conf
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php
Uruchomienie rsync tylko w jednym kierunku powoduje pominięcie nowo utworzonych plików, a na odwrót pominięcie usuniętych plików, porównanie danych wyjściowych diff:
diff -qr old/ new/
daje następujące dane wyjściowe:
Files old/VERSION and new/VERSION differ
Files old/conf/mime.conf and new/conf/mime.conf differ
Only in new/data/pages: playground
Files old/doku.php and new/doku.php differ
Files old/inc/auth.php and new/inc/auth.php differ
Files old/inc/lang/no/lang.php and new/inc/lang/no/lang.php differ
Files old/lib/plugins/acl/remote.php and new/lib/plugins/acl/remote.php differ
Files old/lib/plugins/authplain/auth.php and new/lib/plugins/authplain/auth.php differ
Files old/lib/plugins/usermanager/admin.php and new/lib/plugins/usermanager/admin.php differ
Uruchomienie rsync na dwa sposoby i sortowanie danych wyjściowych w celu usunięcia duplikatów ujawnia, że katalog data/pages/playground/
i plik data/pages/playground/playground.txt
zostały początkowo pominięte:
(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq
daje następujące dane wyjściowe:
VERSION
conf/mime.conf
data/pages/playground/
data/pages/playground/playground.txt
doku.php
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php
rsync
jest uruchamiany z tymi argumentami:
-r
„przekierowywać do katalogów”, -c
aby porównać również pliki o identycznym rozmiarze i tylko „pomiń na podstawie sumy kontrolnej, a nie czasu i rozmiaru mod”, -n
„wykonać jazdę próbną bez zmian”, oraz--out-format="%n"
do „wypisywania aktualizacji za pomocą określonego FORMATU”, czyli „% n” tutaj tylko dla nazwy plikuDane wyjściowe (lista plików) rsync
w obu kierunkach są łączone i sortowane za pomocą sort
, a ta posortowana lista jest następnie zagęszczana poprzez usunięcie wszystkich duplikatów za pomocąuniq
diff new/ old/
), aby zobaczyć, które katalogi zostały usunięte?
diff -qr new/ old/
na powyższym przykładzie ze smoły dokuwiki produkuje taką samą moc jak diff -qr old/ new/
- czyli widać, że katalog jest nowy / brakujące pliki, ale nie w niej
diff
strona podręcznika w CentOS 7 opisuje-q
jako „raportuj tylko wtedy, gdy pliki się różnią”, co jest mniej jasne niż to, co napisałeś.