Różnica między dwoma katalogami w Linuksie
Próbuję znaleźć pliki istniejące w jednym katalogu, ale nie w drugim, próbowałem użyć tego polecenia:
diff -q dir1 dir2
Problem z powyższym poleceniem, że znajduje zarówno pliki w dir1
, ale nie w dir2
, jak i pliki w dir2
, ale nie w dir1
,
Próbuję znaleźć pliki w dir1
, ale nie tylko w dir2
.
Oto mała próbka moich danych
dir1 dir2 dir3
1.txt 1.txt 1.txt
2.txt 3.txt 3.txt
5.txt 4.txt 5.txt
6.txt 7.txt 8.txt
Kolejnym pytaniem w mojej głowie jest jak mogę znaleźć pliki w dir1
ale nie w dir2
lub dir3
w jednym poleceniu?
14 answers
diff -r dir1 dir2 | grep dir1 | awk '{print $4}' > difference1.txt
Explanation:
diff -r dir1 dir2
pokazuje, które pliki są tylko w dir1, a te tylko w dir2, a także zmiany plików obecnych w obu katalogach, jeśli istnieją.-
diff -r dir1 dir2 | grep dir1
pokazuje, które pliki są tylko w dir1 awk
aby wydrukować tylko nazwę pliku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-26 12:41:41
To powinno wystarczyć:
diff -rq dir1 dir2
Opcje wyjaśnione(za pomocą strony man diff (1) ):
-
-r
- rekurencyjnie porównuje znalezione podkatalogi. -
-q
- wypisuje tylko, czy Pliki się różnią.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-27 11:00:39
comm -23 <(ls dir1 |sort) <(ls dir2|sort)
To polecenie da ci pliki, które są w dir1 i , a nie w dir2.
O podpisie <( )
możesz go wygooglować jako "substytucję procesu".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-04 15:56:40
Dobrym sposobem na to porównanie jest użycie find
z md5sum
, a następnie diff
.
Przykład:
Użyj find
, Aby wyświetlić listę wszystkich plików w katalogu, a następnie Oblicz Skrót md5 dla każdego pliku i prześlij go do pliku:
find /dir1/ -type f -exec md5sum {} \; > dir1.txt
Wykonaj tę samą procedurę do innego katalogu:
find /dir2/ -type f -exec md5sum {} \; > dir2.txt
Następnie porównaj wynik dwóch plików z "diff":
diff dir1.txt dir2.txt
Ta strategia jest bardzo przydatna, gdy dwa katalogi do porównania nie są w tej samej maszynie i musisz się upewnić że pliki są równe w obu katalogach.
Innym dobrym sposobem na wykonanie zadania jest użycie git
git diff --no-index dir1/ dir2/
Pozdrawiam!Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-07 00:49:13
Meld ( http://meldmerge.org/) wykonuje świetną robotę przy porównywaniu katalogów i plików wewnątrz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-04 17:02:51
Wtyczka Vima DirDiff jest kolejnym bardzo przydatnym narzędziem do porównywania katalogów.
vim -c "DirDiff dir1 dir2"
Nie tylko wymienia, które Pliki różnią się między katalogami, ale także pozwala sprawdzić/zmodyfikować za pomocą vimdiff pliki, które są różne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-08 22:49:00
Inne (może szybsze dla dużych katalogów) podejście:
$ find dir1 | sed 's,^[^/]*/,,' | sort > dir1.txt && find dir2 | sed 's,^[^/]*/,,' | sort > dir2.txt
$ diff dir1.txt dir2.txt
Polecenie sed
usuwa pierwszy składnik katalogu dzięki postowi Erika)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:31
Trochę za późno, ale może komuś pomóc. Nie wiem, czy diff lub rsync wypluwają tylko nazwy plików w takim gołym formacie. Dzięki plhn za to miłe rozwiązanie, które rozszerzyłem poniżej.
Jeśli chcesz tylko nazwy plików, aby łatwo było skopiować potrzebne pliki w czystym formacie, możesz użyć polecenia Znajdź.
comm -23 <(find dir1 | sed 's/dir1/\//'| sort) <(find dir2 | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'
Zakłada się, że zarówno dir1, jak i dir2 znajdują się w tym samym folderze nadrzędnym. sed po prostu usuwa folder nadrzędny, dzięki czemu można porównać jabłka z jabłkami. Ostatni sed przywraca nazwę dir1.
Jeśli chcesz tylko pliki:
comm -23 <(find dir1 -type f | sed 's/dir1/\//'| sort) <(find dir2 -type f | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'
Podobnie dla katalogów:
comm -23 <(find dir1 -type d | sed 's/dir1/\//'| sort) <(find dir2 -type d | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-14 13:27:50
Przyjęta odpowiedź wyświetli również listę plików, które istnieją w obu katalogach, ale mają inną zawartość. Aby wyświetlić listę tylko plików, które istnieją w dir1, możesz użyć:
diff -r dir1 dir2 | grep 'Only in' | grep dir1 | awk '{print $4}' > difference1.txt
Wyjaśnienie:
- diff-r dir1 dir2: compare
- grep 'Only in': pobiera linie zawierające 'Only in'
- grep dir1: pobiera linie zawierające katalog
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-28 16:35:39
Niezadowolony ze wszystkich odpowiedzi, ponieważ większość z nich działa bardzo powoli i generuje niepotrzebnie długie wyjście dla dużych katalogów, napisałem własny skrypt Pythona, aby porównać dwa foldery.
W przeciwieństwie do wielu innych rozwiązań, nie porównuje zawartości plików. Ponadto nie wchodzi do podkatalogów, których brakuje w innym katalogu. Tak więc wyjście jest dość zwięzłe, a skrypt działa szybko.
#!/usr/bin/env python3
import os, sys
def compare_dirs(d1: "old directory name", d2: "new directory name"):
def print_local(a, msg):
print('DIR ' if a[2] else 'FILE', a[1], msg)
# ensure validity
for d in [d1,d2]:
if not os.path.isdir(d):
raise ValueError("not a directory: " + d)
# get relative path
l1 = [(x,os.path.join(d1,x)) for x in os.listdir(d1)]
l2 = [(x,os.path.join(d2,x)) for x in os.listdir(d2)]
# determine type: directory or file?
l1 = sorted([(x,y,os.path.isdir(y)) for x,y in l1])
l2 = sorted([(x,y,os.path.isdir(y)) for x,y in l2])
i1 = i2 = 0
common_dirs = []
while i1<len(l1) and i2<len(l2):
if l1[i1][0] == l2[i2][0]: # same name
if l1[i1][2] == l2[i2][2]: # same type
if l1[i1][2]: # remember this folder for recursion
common_dirs.append((l1[i1][1], l2[i2][1]))
else:
print_local(l1[i1],'type changed')
i1 += 1
i2 += 1
elif l1[i1][0]<l2[i2][0]:
print_local(l1[i1],'removed')
i1 += 1
elif l1[i1][0]>l2[i2][0]:
print_local(l2[i2],'added')
i2 += 1
while i1<len(l1):
print_local(l1[i1],'removed')
i1 += 1
while i2<len(l2):
print_local(l2[i2],'added')
i2 += 1
# compare subfolders recursively
for sd1,sd2 in common_dirs:
compare_dirs(sd1, sd2)
if __name__=="__main__":
compare_dirs(sys.argv[1], sys.argv[2])
Przykładowe użycie:
user@laptop:~$ python3 compare_dirs.py dir1/ dir2/
DIR dir1/out/flavor-domino removed
DIR dir2/out/flavor-maxim2 added
DIR dir1/target/vendor/flavor-domino removed
DIR dir2/target/vendor/flavor-maxim2 added
FILE dir1/tmp/.kconfig-flavor_domino removed
FILE dir2/tmp/.kconfig-flavor_maxim2 added
DIR dir2/tools/tools/LiveSuit_For_Linux64 added
Lub jeśli chcesz zobaczyć tylko pliki z pierwszego katalogu:
user@laptop:~$ python3 compare_dirs.py dir2/ dir1/ | grep dir1
DIR dir1/out/flavor-domino added
DIR dir1/target/vendor/flavor-domino added
FILE dir1/tmp/.kconfig-flavor_domino added
P. S. jeśli chcesz porównać rozmiary plików i skróty plików pod kątem potencjalnych zmian, opublikowałem zaktualizowany skrypt tutaj: https://gist.github.com/amakukha/f489cbde2afd32817f8e866cf4abe779
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-09 06:43:31
Uproszczony sposób porównywania 2 katalogów za pomocą polecenia DIFF
Nazwa pliku Diff.1 nazwa pliku.2 > nazwa pliku.dat > > Enter
Otwórz nazwę pliku.dat po zakończeniu biegu
I zobaczysz: Tylko w nazwie pliku.1: nazwa pliku.2 Tylko w: directory_name: name_of_file1 Tylko w: directory_Name: name_of_file2
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-25 14:59:34
Kdiff3 ma ładny interfejs diff dla plików i katalogów.
Sprawdź URL: http://kdiff3.sourceforge.net
Działa pod Windows i Linux.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-03 09:02:52
GNU grep
może odwrócić wyszukiwanie za pomocą opcji -v
. To sprawia, że grep
zgłasza linie, które nie pasują. Dzięki temu możesz usunąć pliki w dir2
z listy plików w dir1
.
grep -v -F -x -f <(find dir2 -type f -printf '%P\n') <(find dir1 -type f -printf '%P\n')
Opcje -F -x
mówią grep
, Aby wykonać wyszukiwanie ciągu znaków na całej linii.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-09 07:21:36
Jest to skrypt bash do drukowania poleceń do synchronizacji dwóch katalogów
dir1=/tmp/path_to_dir1
dir2=/tmp/path_to_dir2
diff -rq $dir1 $dir2 | sed -e "s|Only in $dir2\(.*\): \(.*\)|cp -r $dir2\1/\2 $dir1\1|" | sed -e "s|Only in $dir1\(.*\): \(.*\)|cp -r $dir1\1/\2 $dir2\1|"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-07 22:27:27