2008-09-23 20 views
18

Zanim zacząłem używać SVN, zarządzałem moim projektem, po prostu przechowywałem katalog /develop/ oraz edytowałem i testowałem tam pliki, a następnie przenosząc je na numer /main/ informator. Kiedy zdecydowałem się przejść na SVN, musiałem mieć pewność, że katalogi rzeczywiście są zsynchronizowane.Jak porównać pliki o tych samych nazwach w dwóch różnych katalogach przy użyciu skryptu powłoki

Jaki jest więc dobry sposób napisania skryptu powłoki [bash], aby rekurencyjnie porównywać pliki o tej samej nazwie w dwóch różnych katalogach?

Uwaga: Nazwy katalogów użyte powyżej mają charakter przykładowy. Nie polecam przechowywania twojego kodu na najwyższym poziomie :).

Odpowiedz

26

Polecenie diff -r ma możliwość porównywania katalogów rekurencyjnie:

diff -r /develop /main 
+0

Nie technicznie bash, ale lepsze rozwiązanie, jeśli twój diff je obsługuje. – paxdiablo

+4

Działa dla mnie! Dzięki. Ponadto, dla ładniejszego drukowania, diff -ru/develop/main działa również – Animesh

1

[Czytałem gdzieś, że odpowiedzi na swoje pytania jest OK, więc tutaj :)]

Próbowałem to, i to działało całkiem dobrze

[/]$ cd /develop/ 
[/develop/]$ find | while read line; do diff -ruN "/main/$line" $line; done |less 

Możesz porównać tylko określone pliki [np, tylko .php jedynek] edytując powyższą linię jako

[/]$ cd /develop/ 
[/develop/]$ find -name "*.php" | while read line; do diff -ruN "/main/$line" $line; done |less 

Jakieś inne pomysły?

4

Diff mam dostępne pozwala rekurencyjnych różnicami:

diff -r main develop 

ale ze skryptem powłoki:

(cd main ; find . -type f -exec diff {} ../develop/{} ';') 
7
diff -rqu /develop /main 

To tylko daje zestawienie zmian w ten sposób :)

Jeśli chcesz zobaczyć tylko nowe/brakujące plików

diff -rqu /develop /main | grep "^Only 

Jeśli chcesz je gołymi:

diff -rqu /develop /main | sed -rn "/^Only/s/^Only in (.+?): /\1/p" 
+0

Działa to, ale obcina ostatni katalog "ukośnik" jak na przykład: abc/def/ghi wynik jest pokazany jako abc/defghi – iaav

0

Klasyczny (System V Unix) odpowiedź byłaby dircmp dir1 dir2, który był skrypt, który wypisze pliki znalezione w obu dir1 ale nie dir2 lub w dir2, ale nie dir1 na początku (pierwsza strona danych wyjściowych, z komendy pr, czyli w paginacji z nagłówkami), a następnie porównanie każdego wspólnego pliku z analizą (ten sam, inny katalog był najczęstszym wynikiem).

To wydaje się być w trakcie znikania - mam niezależną reimplementację, jeśli jest to potrzebne. To nie jest nauka o rakietach (cmp jest twoim przyjacielem).

1

tutaj jest przykładem (nieco brudny) scenariusz kopalni dircompare.sh, które będą:

  • plików Sortowanie i katalogi w macierzy w zależności od katalogu występują one w (lub oba), w dwa rekurencyjne przechodzi
  • plików, które występują w obu katalogach, są ponownie klasyfikowane w dwóch tablicach, w zależności czy diff -q określa, czy różnią się one lub nie
  • tych plików diff wierzytelności są równe, pokaz i porównanie znaczników czasu

Mam nadzieję, że okaże się przydatny - Pozdrawiam!

EDIT2: (Właściwie działa dobrze z plikami zdalnymi - problem był nieobsługiwany Sygnał Ctrl-C podczas operacji różnicowej między plikiem lokalnym i zdalnym, co może trochę potrwać, skrypt jest teraz zaktualizowany z pułapką do obsługi tego - jednak, pozostawiając poprzednią Edycja odsyłające):

eDIT: ... z wyjątkiem wydaje się rozbić mój serwer do katalogu zdalnego ssh (który próbowałem za pomocą ponad ~/.gvfs) ... Więc to nie jest bash już, ale alternatywą, jak sądzę, jest użycie rsync, oto przykład:

$ # get example revision 4527 as testdir1 
$ svn co https://openbabel.svn.sf.net/svnroot/openbabel/openbabel/trunk/[email protected] testdir1 

$ # get earlier example revision 2729 as testdir2 
$ svn co https://openbabel.svn.sf.net/svnroot/openbabel/openbabel/trunk/[email protected] testdir2 

$ # use rsync to generate a list 
$ rsync -ivr --times --cvs-exclude --dry-run testdir1/ testdir2/ 
sending incremental file list 
.d..t...... ./ 
>f.st...... CMakeLists.txt 
>f.st...... MACCS.txt 
>f..t...... SMARTS_InteLigand.txt 
... 
>f.st...... atomtyp.txt 
>f+++++++++ babel_povray3.inc 
>f.st...... bin2hex.pl 
>f.st...... bondtyp.h 
>f..t...... bondtyp.txt 
... 

zauważyć, że:

  • Aby jak powyżej, nie należy zapominać, krocząca tnie / na końcu nazwy katalogów w rsync
  • --dry-run - symulować tylko, nie aktualizować/transfer plików
  • -r - recurse do katalogów
  • -v - opisowy (ale nie związanych złożyć informacje zmianami)
  • --cvs-exclude - ignorować .svn pliki
  • -i - „--itemize-changes: wyjście zmiana-podsumowanie wszystkich aktualizacji”

Oto krótki fragment man rsync który wyjaśnia informacje wyświetlane przez -i (na przykład , że >f.st...... ciągi powyżej):

The "%i" escape has a cryptic output that is 11 letters long. 
The general format is like the string YXcstpoguax, where Y is 
replaced by the type of update being done, X is replaced by the 
file-type, and the other letters represent attributes that may 
be output if they are being modified. 

The update types that replace the Y are as follows: 

o  A < means that a file is being transferred to the remote 
     host (sent). 

o  A > means that a file is being transferred to the local 
     host (received). 

o  A c means that a local change/creation is occurring for 
     the item (such as the creation of a directory or the 
     changing of a symlink, etc.). 

... 
The file-types that replace the X are: f for a file, a d for a 
directory, an L for a symlink, a D for a device, and a S for a 
special file (e.g. named sockets and fifos). 

The other letters in the string above are the actual letters 
that will be output if the associated attribute for the item is 
being updated or a "." for no change. Three exceptions to this 
are: (1) a newly created item replaces each letter with a "+", 
(2) an identical item replaces the dots with spaces, and (3) an 
.... 

Trochę zagadkowo, ale przynajmniej pokazuje podstawowe porównanie katalogów ponad ssh. Twoje zdrowie!