|
[+] 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.pldoc.pisz.plpdf.pisz.plminister.pev.pl
|