Розніца паміж двума каталогамі ў 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 у адной камандзе?

217

14 адказы

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

<�Моцны> Тлумачэнне:

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

  • дифф -r dir1 dir2 | Grep dir1 паказвае, якія файлы толькі ў dir1

  • AWK для друку толькі імя файла.

311
дададзена
Я б Grep для СТГ як ^ dir1 , каб пераканацца, што я не атрымліваю dir1 з'яўляецца пазней у шляху.
дададзена аўтар Alfe, крыніца
@Alfe Гэта можа быць палепшана. Я выкарыстоўваю $ 4 у якасці прыкладу. У фактах, на маёй фактычнай Ubuntu, дифф адказвае на італьянскай мове. <�Код> $ 4 нармальны для італьянскіх і ангельскіх адказаў, але я не ўпэўнены, што на кожных іншых мовах ...
дададзена аўтар asclepix, крыніца
diff -r dir1 dir2 | grep dir1 | awk '{print $4}' > difference1.txt

<�Моцны> Тлумачэнне:

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

  • дифф -r dir1 dir2 | Grep dir1 паказвае, якія файлы толькі ў dir1

  • AWK для друку толькі імя файла.

311
дададзена
Я б Grep для СТГ як ^ dir1 , каб пераканацца, што я не атрымліваю dir1 з'яўляецца пазней у шляху.
дададзена аўтар Alfe, крыніца
@Alfe Гэта можа быць палепшана. Я выкарыстоўваю $ 4 у якасці прыкладу. У фактах, на маёй фактычнай Ubuntu, дифф адказвае на італьянскай мове. <�Код> $ 4 нармальны для італьянскіх і ангельскіх адказаў, але я не ўпэўнены, што на кожных іншых мовах ...
дададзена аўтар asclepix, крыніца

Гэта павінна зрабіць працу:

diff -rq dir1 dir2

Опцыі патлумачылі (праз дифф (1) чалавека старонка ):

  • -r - Recursively compare any subdirectories found.
  • -q - Output only whether files differ.
84
дададзена
Толькі нататка на -q варыянт: Чалавек старонкі толькі сказаць: «Выхад толькі ці адрозніваюцца файлы», а не як ён правярае, калі яны розныя. Я прагледзеў зыходны код і выявіў, што ён правярае толькі памеры файлаў, каб вызначыць адрозненні, а не фактычнае змесціва.
дададзена аўтар ryancdotnet, крыніца
Nice! Але я думаю, што ён павінен быць прадоўжаны так: дифф -rq dir1 dir2 | Grep 'Толькі ў dir1 /'
дададзена аўтар sobi3ch, крыніца
Гэта параўнанне па змесціве, але можа заняць шмат часу на павольных дысках.
дададзена аўтар Smeterlink, крыніца
comm -23 <(ls dir1 |sort) <(ls dir2|sort)

Гэтая каманда дасць вам файлы тыя ў dir1 і не у dir2.

About <( ) sign, you can Google it as 'process substitution'.

42
дададзена
было б добра працаваць і з падкаталогамі, я думаю, (LS -R dir1 | сартаванне) можа зрабіць трук
дададзена аўтар ulkas, крыніца
@ulkas, выхад можа быць няправільным, калі вы выкарыстоўваеце (L -R рэж | сартавання) .
дададзена аўтар Andriy Makukha, крыніца
Гэта будзе працаваць у рэжыме аднаўлення OS X.
дададзена аўтар Anthony Vanover, крыніца

Добры спосаб зрабіць гэта параўнанне, каб выкарыстоўваць знайсці з md5sum , то дифф .

прыклад:

Выкарыстоўвайце знайсці , каб пералічыць усе файлы ў каталогу, то вылічыць md5 Хэш для кожнага файла і трубы яго ў файл:

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

Выканайце тую ж працэдуру ў іншы каталог:

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

Затым параўнайце вынік два файла з «дифф»:

diff dir1.txt dir2.txt

Гэтая стратэгія вельмі карысная, калі два каталога, каб быць параўнальны не ў той жа машыне, і вы павінны пераканацца, што файлы аднолькавыя ў абодвух каталогах.

Another good way to do the job is using git

git diff --no-index dir1/ dir2/

З найлепшымі пажаданнямі!

18
дададзена

Meld ( http://meldmerge.org/ ) робіць вялікую працу ў параўнанні каталогаў і файлаў ўнутры.

Meld comparing directories

10
дададзена
Так, гэта не <�я> пазначыць лінейныя заканчэння. Гэта (неаднаразова) прывяло да распрацоўшчыкаў, якія выкарыстоўваюць гэты інструмент, які здзяйсняе змены, якія «фіксаваныя» канчаткаў лініі, зрабіўшы CRLF ў CRLFLF, напрыклад.
дададзена аўтар 0xC0000022L, крыніца
Акрамя Meld робіць паршывы працу, калі справа даходзіць да лініі канчаткаў ...
дададзена аўтар 0xC0000022L, крыніца
Ён таксама настойвае на чытанне змесціва файла, і таму практычна бескарысны з >> 1 Гб каталогаў.
дададзена аўтар Tomislav Nakic-Alfirevic, крыніца
Ніколі не было праблем з знакамі канца радка. Ці можаце вы падрабязней?
дададзена аўтар Catalin Hritcu, крыніца

Вім з DirDiff убудова яшчэ адзін вельмі карысны інструмент для параўнання каталогаў.

vim -c "DirDiff dir1 dir2"

Гэта не толькі спісы, якія файлы розныя паміж каталогамі, але і дазваляе вам праглядаць/змяняць з vimdiff файлаў, якія адрозніваюцца.

10
дададзена

Іншы (магчыма хутчэй для вялікіх каталогаў) падыход:

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

<�Код> СЕПГ каманда выдаляе першы каталог кампанент дзякуючы Erik`s паведамленні )

5
дададзена
Я лічу, што гэты метад прасцей (па-ранейшаму выкарыстоўваючы знайсці такім чынам каментар, а не асобны адказ): CD dir2; знайсці. -exec [-e ../ dir1/{}] \; -о -print 2>/DEV/нуль Гэта будзе друкаваць файлы, прысутныя ў dir2, але не прысутныя ў dir1.
дададзена аўтар Alexander Amelkin, крыніца

Прыняты адказ будзе таксама спіс файлаў, якія існуюць у абодвух каталогах, але маюць рознае ўтрыманне. Для таго, каб пералічыць толькі тыя файлы, якія існуюць у dir1 вы можаце выкарыстаць:

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

тлумачэнне:

  • дифф -r dir1 dir2: параўнаць
  • Grep 'толькі ў': атрымаць радкі, якія ўтрымліваюць 'толькі ў'
  • Grep dir1: атрымаць радкі, якія ўтрымліваюць тэчка
4
дададзена

Нездаволены з усімі адказамі, так як большасць з іх працуе вельмі павольна і вырабляць залішне доўгі выснова для вялікіх каталогаў, я напісаў уласны сцэнар 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 i1l2[i2][0]:
            print_local(l2[i2],'added')
            i2 += 1
    while i1

Прыклад выкарыстання:

[email protected]:~$ 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

Ці, калі вы хочаце ўбачыць толькі файлы з першага каталога:

[email protected]:~$ 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. If you need to compare file sizes and file hashes for potential changes, I published an updated script here: https://gist.github.com/amakukha/f489cbde2afd32817f8e866cf4abe779

4
дададзена
Досыць просты скрыпт, які робіць менавіта тое, што я хацеў: Пераканайцеся насыпны копію: +1 ад мяне. (Пераўтварыць патрэбу ў python2 хоць) Падказка: выкарыстанне мностваў можа зрабіць дифф частка прасцей.
дададзена аўтар Jason Morgan, крыніца

Гэта трохі позна, але можа камусьці дапамагчы. Не ўпэўнены, што калі дифф або Rsync выплюнуць толькі імёны файлаў, у голым выглядзе, як гэта. Дзякуючы plhn для надання што прыгожае рашэнне, якое я дапоўненай ніжэй.

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

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/'
4
дададзена
Таксама зьвярніце ўвагу, што ваша рашэнне можа не калі файлы з пэўнымі адмысловымі знакамі прысутнічаюць, калі ў вас ёсць вельмі апошнюю версію Прдч з падтрымкай -z (прыйшоў з git.savannah.gnu.org/cgit/coreutils.git/commit/&hellip ; ) вы можаце зрабіць Comm -23 -z <(CD dir1 && знайсці -тыпу ф -print0 | сартаваць -z) <(CD dir2 && знайсці -тыпу е -print0 | сартаваць -z) . (У той жа час я таксама зразумеў, што Выхад s можа быць заменены.)
дададзена аўтар phk, крыніца
Звярніце ўвагу, што вы маглі б зрабіць CD да знайсці замест таго, каб выкарыстоўваць </патч у код>, напрыклад: Comm -23 <(кд dir1 || выхад, знайсці -тыпу п | сартаваць) <(CD dir2 || выхад, знайсці -тыпу п | сартаваць) . (Элемент Выхад s тут, каб прадухіліць знайсці ад выкарыстання бягучага каталога варта CD пацярпець няўдачу.)
дададзена аўтар phk, крыніца

kdiff3 мае прыемны інтэрфейс адрозненняў для файлаў і каталогаў.

Check the URL: http://kdiff3.sourceforge.net

It works under Windows & Linux.

0
дададзена

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 , каб выканаць пошук радкі па ўсёй лініі.

0
дададзена

Спрошчаны спосаб параўнання 2 каталогі з дапамогай каманды DIFF

diff filename.1 filename.2 > filename.dat >>Enter

адкрытая filename.dat пасля запуску завершана

і вы ўбачыце: Толькі ў filename.1: filename.2 Толькі ў: directory_name: name_of_file1 Толькі ў: directory_name: name_of_file2

0
дададзена
Чаму вы павінны выводзіць у .dat файл?
дададзена аўтар Vishnu N K, крыніца