ďťż
 
 
   [+] bash - porównywanie katalogów za pomocą diff
 
 

Tematy

 
    
 

 

 

 

[+] bash - porównywanie katalogów za pomocą diff





RRH - 03-12-2007 00:55
Witam serdecznie!

Piszę sobie prościutki skrypt do tworzenia kopii zapasowej, ale z racji mojej maluteńkiej wiedzy na temat basha napotykam na problemy.
Stanąłem na etapie porównywania dwóch katalogów. Niby rezultat jest dobry, ale nie wiem czy robię to dobrze i czy może istnieje lepszy sposób na dokonanie tego.
Ale od początku.

Na początku zapisuje strukturę drzewa jednego i drugiego katalogu do osobnych plików, nazwijmy je: katalog1Zaw i katalog2Zaw.

plik katalog1Zaw plik01
plik02
plik03
katalog/plik01
katalog/plik02
katalog/plik03 plik katalog2Zaw
katalog/plik01
katalog/plik02
plik01
plik03 Jakimś cudem udało mi się porównać oba pliki, takim sposobem:
diff --change-group-format=' %<' katalog1Zaw katalog2Zaw wynik jest taki: plik01
plik02
plik03
katalog/plik01
katalog/plik02
katalog/plik03 Jeżeli po lewej kolumnie (kolumny są rozdzielone spacją) nic nie ma lub jest, to pliki się powtarzają.
Jeżeli po w prawej kolumnie jest nazwa pliku, to należy przekopiować ten plik do katalogu drugiego.

Napisałem jakimś cudem, bo za nic nie mogłem rozgryźć, co do czego służy w diff.
Istnieją formaty grupy i formaty linii. I pomimo czytania podręcznika systemowego, nie potrafię poprawnie posługiwać się new-group-format, old-group-format, changed-group-format, unchanged-group-format.
W sieci też nie znalazłem żadnych wyjaśnień.
Dlatego pytam się, czy istnieje inny sposób na wyświetlenie różnicy w plikach w takim formacie, jaki przedstawiłem.
Fajnie byłoby, gdyby znalazła się osoba, która w prosty sposób wytłumaczyłaby mi działanie tego potworka, którego przypadkiem napisałem.

To jedna sprawa. Druga jak zapisać ten wynik, aby był bardziej zrozumiały - aby wyglądał np. tak:
[katalog1]    [katalog2]          [kopiowanie]
----------------------------------------------
plik01                                  TAK
plik02                                    NIE
plik03                                    NIE
katalog/plik01                        NIE
katalog/plik02                        NIE
katalog/plik03                        TAK To znaczy, jak zapisać w bashu:
- jeżeli nic nie pisze w lewej kolumnie, skopiuj np. plik01 do katalogu2
- jeżeli jest nazwa pliku w lewej kolumnie, nie nie kopiuj.
Podejrzewam, że aby uzyskać takie kolumny i informacje (TAK, NIE) trzeba użyć sed, ale problem w tym, że nie wiem z jakiej strony się za to zabrać.

Problem dla mnie trudny, ale wierzę, że dla wielu z Was banalny.
Jeżeli znajdzie się osoba, która poświęci swój cenny czas za zerknięcie na ten problem, to będę ogromnie wdzięczny.

Pozdrawiam i liczę na Wasz odzew.



salmon - 03-12-2007 10:24
Po pierwsze, w obu plikach nazwy musisz mieć w tej samej kolejności.
Może mały przykładzik:
Masz dwa pliki:
1 plik1
plik2
katalog/plik1
katalog/plik2 2
plik1
katalog/plik2
katalog/plik3
katalog/plik5 Zakładamy, że plik 1 jest aktualnym spisem katalogu, a 2 tym z kopi zapasowej. Chcesz więc wiedzieć co powinieneś dodać lub usunąć z pliku 2. Wykonujesz diff 2 1 a na wyjściu masz to: 1a2,3
> plik2
> katalog/plik1
3,4d4
< katalog/plik3
< katalog/plik5 Opis wyjścia:

1a2,3
> plik2 dodano plik 2
> katalog/plik1 dodano kataolog/plik2
3,4d4
< katalog/plik3 usunięto katalog/plik3
< katalog/plik5 usunieto katalog/plik5
Reszta rzeczy z wyjścia diffa Cię nie obchodzi. Jak widzisz interesują cię znaki "<" i ">", wyjście można obrobić przy pomocy awk.
Oczywiście istnieją pewnie lepsze narzędzia do robienia kopi zapasowej :)



RRH - 03-12-2007 12:33
salmon dzięki za zainteresowanie!

Twój opis jest dobry, ale myślę, że do porównywania lepszy będzie wynik:

    plik01
plik02
plik03
katalog/plik01
katalog/plik02
    katalog/plik03 gdzie od razu widać, że w drugim katalogu brakuje plik01 i katalog/plik03.
Tylko, jak pisałem w poście wyżej, nie wiem jak to porównać.
Najbardziej jednak interesuje mnie takie wyjście z opisem, ale również nie wiem jak to zrobić. :(

Chciałbym się również dowiedzieć, dlaczego działa
diff --change-group-format=' %<' katalog1Zaw katalog2Zaw a nie działa to:

diff --changed-group-format='%> ' pendZaw dyskZaw pozdrawiam



salmon - 03-12-2007 16:36

gdzie od razu widać, że w drugim katalogu brakuje plik01 i katalog/plik03. Może dla człowieka, nie dla skryptu.
a nie działa to: Co znaczy "nie działa"?

A tak w ogóle jak ma ten skrypt wyglądać bo nie jestem pewny? Chcesz żeby generował Ci raport o różnicach w katalogach, czy żeby automatycznie synchronizował zawartość kopi zapasowej z katalogiem?



RRH - 06-12-2007 02:44
Po pierwsze przepraszam, że tak długo nie pisałem.
Jak ma wyglądać skrypt?
Mam sobie kilka katalogów, w tym jeden na ntfs, które potrzebuję często archiwizować.
Kopia zapasowa będzie kopiowana na pendrive.
Skrypt będzie porównywał pliki zapisane na dysku z plikami na pendrivie i kopiował na nośnik wymienny te pliki, których on nie ma (kopia różnicowa).
To właściwie tyle.

Porównanie już częściowo rozwiązałem. A zrobiłem to tak:

skrypt tworzy mi strukturę drzewa dwóch katalogów, dodając na końcu znak separatora:

katalog1
plik01:
plik02:
plik03:
katalog/plik01:
katalog/plik02:
katalog/plik03: katalog2
plik01:
plik03:
katalog/plik01:
katalog/plik02: Sprawdzam, czy pliki się różnią, dodając przed nazwami plików, których nie ma w katalog2 znak separatora ":",

diff --changed-group-format=':%<' katalog1 katalog2 różnica
:plik01:
plik02:
plik03:
katalog/plik01:
katalog/plik02:
:katalog/plik03: Teraz analizuję różnicę na podstawie lewej kolumny:
cut -d: -f1 roznica co daje:

plik02
plik03
katalog/plik01
katalog/plik02 Jeżeli linia jest pusta, kopiuję plik, to kopiuję np.plik01 do katalog2.
Jeżeli zaś jest tam nazwa pliku, to sprawdzam, czy na dysku jest nowsza wersja i ewentualnie kopiuję.
Teraz mam problem, bo nie wiem, jak przelatywać pętlą linia po linii (wczytywać ją), ale o to zapytam w innym topicu.

Napisz jeszcze proszę, co sądzisz o takim rozwiązaniu, bo mi wydawało się, że do prostego tworzenia backupów, lepiej napisać skrypt w bashu.

pozdrawiam i dzięki za zainteresowanie



salmon - 06-12-2007 11:02
A może po prostu tak:
rsync -az --delete  źródło cel



RRH - 09-12-2007 01:12
Przecież rsync służy do wykonywania kopii zapasowych poprzez sieć, no chyba, że się mylę.
Jak znasz jakiś prosty program do robienia kopii zapasowych danych to daj znać. Ja jeszcze poszukam.
Bo chyba lepiej znaleźć jakiś program, niż wymyślać na nowo koło.

Pozdrawiam.



salmon - 09-12-2007 07:07
Przecież Ci napisałem już. źródło i cel to ścieżki do katalogów, pierwszy to katalog, który chcesz wrzucić jako kopię zapasową, a drugi miejscem gdzie chcesz to zapisać.



RRH - 09-12-2007 23:53
Tak, napisałeś - przepraszam za zamieszanie.

Jak dodaje się więcej katalogów źródłowych, to pomocna jest opcja -R:
rsync -azR --delete  źródło1 źródło2 cel Jeszcze pytanie dodatkowe. Czy da się to samo uzyskać samym tarem?
Bo przelotnie przejrzałem mana i dołączania nowszych plików, ale chyba nie ma usuwania starych.
Tak tylko pytam, bo jestem ciekawy.

Pozdrawiam.



salmon - 10-12-2007 00:47

Czy da się to samo uzyskać samym tarem? Jedyna odpowiedź jaka mi przychodzi do głowy to: Sprawdź. W podręczniku systemowym niby jest napisane, że jest opcja --delete dla usuwania i -A dla dołączania, ale jak to działa to nie mam pojęcia.



RRH - 10-12-2007 15:18
dobra, chociaż zrobiło się offtopicowo, to temat uważam za rozwiązany

punkcik dla Ciebie!

wielkie dzięki!

pozdrawiam
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • minister.pev.pl

  •  

     


     

     
    Copyright 2003. MĂłj serwis