Разница между двумя каталогами в Linux



Я пытаюсь найти файлы, существующие в одном каталоге, но не в другом, я попытался использовать эту команду:



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 в одной команде?

580   14  

14 ответов:

diff -r dir1 dir2 | grep dir1 | awk '{print }' > difference1.txt

пояснение:

  • diff -r dir1 dir2 показывает, какие файлы находятся только в dir1 и только в dir2, а также изменения файлов, присутствующих в обоих каталогах, если таковые имеются.

  • diff -r dir1 dir2 | grep dir1 показывает, какие файлы находятся только в dir1

  • awk для печати только имя файла.

Это должно сделать работу:

diff -rq dir1 dir2

параметры объяснены (через diff (1) на странице):

  • -r - рекурсивно сравнить все найденные подкаталоги.
  • -q - вывод только ли файлы отличаются.
comm -23 <(ls dir1 |sort) <(ls dir2|sort)

эта команда даст вам файлы, которые находятся в dir1 и не в директория dir2.

о <( ) знак, вы можете погуглить его как "процесс замены".

хороший способ сделать это сравнение, чтобы использовать find С md5sum, потом diff.

пример:

использовать find чтобы перечислить все файлы в каталоге, затем вычислите хэш md5 для каждого файла и передайте его в файл:

find /dir1/ -type f -exec md5sum {} \; > dir1.txt

проделайте ту же процедуру с другим каталогом:

find /dir2/ -type f -exec md5sum {} \; > dir2.txt

затем сравните результат двух файлов с "diff":

diff dir1.txt dir2.txt

эта стратегия очень полезна при сравнении двух каталогов находятся не на одной машине, и вам нужно убедиться, что файлы равны в обоих каталогах.

еще один хороший способ сделать работу с помощью git

git diff --no-index dir1/ dir2/

С наилучшими пожеланиями!

Meld (http://meldmerge.org/) отлично справляется с сравнением каталогов и файлов внутри.

Meld comparing directories

vim DirDiff плагин является еще одним очень полезным инструментом для сравнения каталогов.

vim -c "DirDiff dir1 dir2"

Он не только перечисляет, какие файлы отличаются между каталогами, но также позволяет проверять/изменять с помощью vimdiff файлы, которые отличаются.

другой (возможно, более быстрый для больших каталогов) подход:

$ find dir1 | sed 's,^[^/]*/,,' | sort > dir1.txt && find dir2 | sed 's,^[^/]*/,,' | sort > dir2.txt
$ diff dir1.txt dir2.txt

The sed команда удаляет первый компонент каталога благодаря)

Это немного поздно, но может кому-то помочь. Не уверен, что diff или rsync выплюнуть только имена файлов в голом формате, как это. Спасибо plhn за предоставление этого приятного решения, которое я расширил ниже.

Если вы хотите только имена файлов, так что это легко просто скопировать файлы, которые вам нужны в чистом формате, вы можете использовать команду find.

comm -23 <(find dir1 | sed 's/dir1/\//'| sort) <(find dir2 | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'

предполагается, что dir1 и dir2 находятся в одной родительской папке. СЭД просто удаляет родительскую папку, чтобы вы могли сравнить яблоки с яблоками. Последний sed просто возвращает имя 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 }' > difference1.txt

объяснение:

  • diff-r dir1 dir2: сравнить
  • grep 'Only in': получить строки, содержащие 'Only in'
  • grep dir1: получить строки, содержащие dir

неудовлетворенный всеми ответами, так как большинство из них работают очень медленно и производят излишне длинный вывод для больших каталогов, я написал свой собственный скрипт 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

упрощенный способ сравнения 2 каталогов с помощью команды DIFF

diff filename.1 имя файла.2 > имя_файла.dat > > Enter

открыть именем.dat после завершения запуска

и вы увидите: Только в имени файла.1: имя.Два Только в параметра directory_name: name_of_file1 Только в параметра directory_name: name_of_file2

kdiff3 имеет хороший интерфейс diff для файлов и каталогов.

Проверьте URL:http://kdiff3.sourceforge.net

Он работает под Windows и Linux.

GNU grep можно инвертировать поиск с помощью опции -v. Это делает grep отчет о строках, которые не совпадают. При этом вы можете удалить файлы dir2 из списка файлов в dir1.

grep -v -F -x -f <(find dir2 -type f -printf '%P\n') <(find dir1 -type f -printf '%P\n')

опции -F -x рассказать grep для выполнения строкового поиска по всей строке.

это скрипт bash для печати команд для синхронизации двух каталогов

dir1=/tmp/path_to_dir1
dir2=/tmp/path_to_dir2
diff -rq $dir1 $dir2 | sed -e "s|Only in $dir2\(.*\): \(.*\)|cp -r $dir2/ $dir1|" |  sed -e "s|Only in $dir1\(.*\): \(.*\)|cp -r $dir1/ $dir2|" 

Comments

    Ничего не найдено.