Я'пытаюсь найти файлы, существующие в одном каталоге, но не в другом, я пытался использовать эту команду:
diff -q dir1 dir2
Проблема в том, что команда находит как файлы в dir1
, но не в dir2
, так и файлы в dir2
, но не в dir1
,
Я пытаюсь найти файлы только в dir1
, но не в dir2
.
Вот небольшой пример того, как выглядят мои данные
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
Еще один вопрос: как я могу найти файлы в dir1
, но не в dir2
или dir3
в одной команде?
diff -r dir1 dir2 | grep dir1 | awk '{print $4}' > difference1.txt
Пояснение:
diff -r dir1 dir2
показывает, какие файлы находятся только в каталоге dir1, а какие только в каталоге dir2, а также изменения файлов, присутствующих в обоих каталогах, если таковые имеются.
diff -r dir1 dir2 | grep dir1
показывает, какие файлы находятся только в каталоге dir1
awk
для печати только имени файла.
Это должно сделать работу:
diff -rq dir1 dir2
Параметры объяснил (через дифф(1) страницу):
-Р
- рекурсивно сравниваем найденных подкаталогов.-м
- вывод только о том, что файлы отличаются.Хороший способ сделать это сравнение, чтобы использовать найти
в команду md5sum
, затем различия
.
Пример:
Использовать найти
в список все файлы в каталоге, затем вычислить MD5-хэш для каждого файла и вставьте его в файл:
find /dir1/ -type f -exec md5sum {} \; > dir1.txt
Делать ту же процедуру на другой каталог:
find /dir2/ -type f -exec md5sum {} \; > dir2.txt
Затем сравнить результаты двух файлов с "разница" в:
diff dir1.txt dir2.txt
Эта стратегия очень полезна, когда две директории, которые надо сравнивать не в той же машине, и вы должны убедиться, что файлы одинаковы в обоих каталогах.
Еще один хороший способ, чтобы выполнить задание использует мерзавец
git diff --no-index dir1/ dir2/
С наилучшими пожеланиями!
Плагин vim'a DirDiff - еще один очень полезный инструмент для сравнения каталогов.
vim -c "DirDiff dir1 dir2"
Он не только перечисляет, какие файлы отличаются между каталогами, но и позволяет вам проверять/изменять с помощью vimdiff файлы, которые отличаются.
Недовольны все ответы, так как большинство из них очень медленно работать и производить длинные выходные неоправданно большие каталоги, я написал свой скрипт на Python, чтобы сравнить две папки.
В отличие от многих других решений, он не'т сравнить содержимое файлов. Также он не'т пойти внутри подкаталогов, которые отсутствуют в другой каталог. Поэтому выход достаточно лаконичной и скрипт работает быстро.
#!/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])
Пример использования:
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
Или если вы хотите увидеть только файлы из первого каталога:
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. Если вам нужно сравнить размеры файлов и файлов хэши для потенциальных изменений, я опубликовал обновленный скрипт здесь: https://gist.github.com/amakukha/f489cbde2afd32817f8e866cf4abe779
Другой (может быть быстрее для больших каталогах) подход:
$ find dir1 | sed 's,^[^/]*/,,' | sort > dir1.txt && find dir2 | sed 's,^[^/]*/,,' | sort > dir2.txt
$ diff dir1.txt dir2.txt
В СЭД
команда удаляет первый компонент каталога благодаря посту Эрика)
Этот ответ оптимизирует одно из предложений от @Adail-младший, добавив опцию -Д
, что полезно, когда ни один из каталогов сравниваются git-репозиториев:
git diff -D --no-index dir1/ dir2/
Если вы используете -Д
, то вы выиграли'т вижу сравнения с /dev/нуль
:
текст Бинарные файлы/что и /dev/нуль отличаться
Это немного поздно, но может кому-то помочь. Не уверен, если дифф или rsync выплюнуть просто имена в голой формате. Благодаря plhn для дачи, что хорошее решение, которое я расширены ниже.
Если вы хотите просто имена файлов, так что's легко, просто скопируйте нужные вам файлы в чистом формате, вы можете использовать команду find.
comm -23 <(find dir1 | sed 's/dir1/\//'| sort) <(find dir2 | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'
Это предполагает, что оба dir1 и dir2 в той же родительской папке. СЭД просто удаляет родительскую папку, так что вы можете сравнивать яблоки с яблоками. Последние СЭД просто ставит dir1 и имя.
Если вы просто хотите файлов:
comm -23 <(find dir1 -type f | sed 's/dir1/\//'| sort) <(find dir2 -type f | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'
Аналогично для каталогов:
comm -23 <(find dir1 -type d | sed 's/dir1/\//'| sort) <(find dir2 -type d | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'
Принято отвечать также список файлов, которые есть в обоих каталогах, но имеют различное содержание. В списке только файлы, которые существуют в dir1 вы можете использовать:
diff -r dir1 dir2 | grep 'Only in' | grep dir1 | awk '{print $4}' > difference1.txt
Объяснение:
kdiff3 имеет приятный интерфейс копирования файлов и каталогов.
Он работает на Windows, Linux, и macOS.
Вы можете установить ее несколькими способами:
квас бочковой установить kdiff3
Это bash-скрипт на команды печати для синхронизации двух каталогов
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|"
Упрощенный способ сравнить 2 папки, используя команду diff
дифф именем.1 именем.2 > именем.дат >>введите
открыть именем.DAT после завершения выполнения
и вы увидите: Только в имени файла.1: имя.2 Только в параметра directory_name: name_of_file1 Только в параметра directory_name: name_of_file2
Грэп ГНУ может обратный поиск с опцией -в
. Это делает команда grep
отчетность строк, которые не совпадают. При этом вы можете удалить файлы в директории dir2из списка файлов в директорию dir1
.
grep -v -F -x -f <(find dir2 -type f -printf '%P\n') <(find dir1 -type f -printf '%P\n')
Опции -F-х
сказать команда grep
, чтобы проанализировать строку поиска на всей линии.