Jak utworzyć listę zmodyfikowanych plików programowo przy użyciu narzędzi wiersza poleceń systemu Linux? Nie interesuje mnie różnica w żadnym konkretnym pliku (delta, łatka). Chcę tylko mieć listę nowych lub zmodyfikowanych plików w porównaniu do poprzedniej wersji produktu. Aby móc opublikować nową aktualizację produktu.
aktualizacja: diff -qr
nie daje bardzo wygodnych wyników. Dane wyjściowe diff -qr
również muszą zostać przetworzone. Czy jest jakiś lepszy sposób?
linux
bash
command-line
diff
Alfa Syzyf
źródło
źródło
Odpowiedzi:
Mam do tego proste podejście: użyj trybu podglądu rsync:
Pliki oznaczone jako „do usunięcia” za pomocą tego polecenia będą plikami „nowymi”. Pozostałe, które mają zostać przeniesione, zmieniły się w jakiś sposób. Więcej informacji znajduje się na stronie rsync-man-page.
źródło
Można użyć diff toool: patrz opcje -q oraz -r
Przykład:
źródło
Only in
które pojawiają się, nawet jeśli katalogi są idealnymi kopiami. Musiałem porównać zmiany ze starą wersją i ostatecznie pobrać całą wersję do osobnego katalogu i użyć standardowych narzędzi SVN do porównania. To chyba jedyna droga…diffutils
Pakiet zawieralsdiff
narzędzia. Wystarczy przekazać dane wyjściowediff -u
do lsdiff:źródło
patchutils
pakiecie dla mnie (CentOS 5.x).Chciałbym tylko dotknąć pliku w momencie każdej aktualizacji, a następnie można znaleźć pliki, które zostały zmodyfikowane od tego czasu za pomocą
find /tree/location -newer /last/update/file -print
źródło
Aby wziąć tylko nazwę plików, które zmienili, używam tego polecenia:
Jeśli chcesz wykluczyć niektóre pliki jako pliki obiektów lub pliki bibliotek, możesz użyć:
źródło
Aby utworzyć listę nowych lub zmodyfikowanych plików programowo najlepszym rozwiązaniem, jakie mogłem wymyślić, jest użycie rsync , sort i uniq :
Pozwól mi wyjaśnić za pomocą tego przykładu: chcemy porównać dwie wersje dokuwiki, aby zobaczyć, które pliki zostały zmienione, a które nowo utworzone.
Ściągamy smoły za pomocą wget i wyodrębniamy je do katalogów
old/
oraznew/
:Uruchomienie rsync w jedną stronę może spowodować pominięcie nowo utworzonych plików, ponieważ porównanie rsync i diff pokazuje tutaj:
daje następujące dane wyjściowe:
Uruchomienie rsync tylko w jednym kierunku powoduje pominięcie nowo utworzonych plików, a na odwrót pominięcie usuniętych plików, porównanie danych wyjściowych diff:
daje następujące dane wyjściowe:
Uruchomienie rsync na dwa sposoby i sortowanie danych wyjściowych w celu usunięcia duplikatów ujawnia, że katalog
data/pages/playground/
i plikdata/pages/playground/playground.txt
zostały początkowo pominięte:daje następujące dane wyjściowe:
rsync
jest uruchamiany z tymi argumentami:-r
„przekierowywać do katalogów”,-c
aby również porównać pliki o identycznym rozmiarze i tylko „pomiń na podstawie sumy kontrolnej, a nie czasu i rozmiaru mod”,-n
„wykonać jazdę próbną bez zmian”, oraz--out-format="%n"
do „wypisywania aktualizacji za pomocą określonego FORMATU”, czyli „% n” tutaj tylko dla nazwy plikuDane wyjściowe (lista plików)
rsync
w obu kierunkach są łączone i sortowane za pomocąsort
, a ta posortowana lista jest następnie zagęszczana poprzez usunięcie wszystkich duplikatów za pomocąuniq
źródło
Powinieneś uzyskać pożądany efekt za pomocą:
źródło
To może załatwić sprawę:
źródło
Zwykle umieszczasz pliki w jakimś systemie kontroli wersji, takim jak SubVersion lub git, ponieważ mogą to zrobić po wyjęciu z pudełka.
Ale możesz zrobić szybki skrypt z pętlą for na dir1, a następnie porównać każdy plik z plikiem w dir2. Pętla for może spojrzeć na kod wyjścia z diff, aby dowiedzieć się, czy pliki były inne.
Może coś takiego:
Uwaga: Skrypt nie jest testowany, więc powyższy przykład to „pseudokod inspirowany bash” ...
Spróbujmy jeszcze raz, ale z git
Utwórz przykładowe pliki do gry
Następnie wpisz katalog i zaimportuj katalog1
Wyjdź i zmodyfikuj katalog 1 (aby stał się katalogiem 2)
Następnie przejdź do katalogu git i zaimportuj nowy katalog
Teraz zapytaj gita, co się zmieniło (za pomocą polecenia status)
Dane wyjściowe to lista zmian, która wygląda następująco:
źródło
Może byłbyś szczęśliwszy z czegoś innego. Spróbować
git
.Zrób to jako przykład:
git
śledzi twoje pliki za ciebie. Poleceniegit status
pokaże wszystkie pliki, które zostały zmodyfikowane od ostatniego zatwierdzenia.źródło
Jest to podobne do rsync: pokazuje, kiedy nowszy plik docelowy ma zostać zastąpiony (zapytany później, ale nie duplikat).
Jak wskazano w pytaniu, „diff -q -r” może wymagać pewnego przetwarzania, aby było przydatne. Pytanie nie określiło formy wyniku; odpowiedzi dają różne rodzaje raportów.
rsync
jest przydatnym narzędziem do tego celu, ponieważ jest znacznie szybszy niżdiff
. Jednak rozwiązanie sugerowane przez @nils jest znacznie bardziej szczegółowe (i wyświetla więcej plików) niż faktyczne różnice między starymi / nowymi drzewami katalogów. Na przykład porównując to ze skryptem, który napisałem dla tej odpowiedzi i działając na tych samych danych,Aby
diff
poprawnie uwzględnić nowe pliki, potrzebujesz również-N
opcji (której nie widzę w żadnej z sugerowanych odpowiedzi). Ponieważ jednak jest on znacznie wolniejszy (rzędy wielkości) niżrsync
poprawa wydajności tego drugiego wydaje się być dobrym rozwiązaniem.Dalsza lektura
źródło
Zawsze byłem stronniczy w stosunku do sha1sum (lub nawet md5sum; w tym kontekście jest to całkiem bezpieczne).
Czasami - tak jak w przypadku zmiany nazwy lub przenoszenia wielu plików - sortowanie w pierwszym polu, a następnie wykonanie różnicy może pomóc, ale w większości przypadków jest to wystarczające.
Zauważ, że w porównaniu do niektórych innych metod ma to tę zaletę, że nie musisz przechowywać kopii plików „przed”; tylko plik wyjściowy md5sum.
źródło