Mam pytanie dotyczące polecenia diff, jeśli chcę rekursywnego porównania katalogu, ale tylko dla określonego typu pliku, jak to zrobić?
Próbowałem użyć opcji wykluczania, ale mogę użyć tylko jednego wzorca:
$ diff /destination/dir/1 /destination/dir/2 -r -x *.xml
z poleceniem mogę tylko wyklucza typ pliku xml, chociaż istnieją pliki w folderze typu obrazu ( png
, gif
, jpg
) txt
, php
itp
jak porównać tylko niektóre typy plików.
Odpowiedzi:
Możesz podać
-x
więcej niż jeden raz.diff -x '*.foo' -x '*.bar' -x '*.baz' /destination/dir/1 /destination/dir/2
Z sekcji Porównanie katalogów
info diff
(w moim systemie muszę to zrobićinfo -f /usr/share/info/diff.info.gz
):źródło
Zaczerpnięte z (wersji) strony podręcznika:
-x PAT --exclude=PAT Exclude files that match PAT. -X FILE --exclude-from=FILE Exclude files that match any pattern in FILE.
Wygląda więc na to, że
-x
raport akceptuje tylko jeden wzorzec, ale jeśli umieścisz w pliku wszystkie wzorce, które chcesz wykluczyć (prawdopodobnie jeden w każdym wierszu), możesz użyć drugiej flagi w następujący sposób:gdzie exclude.pats to:
źródło
find . -type f -not -name '*.<my-ext>' | xargs -I% basename '%' | awk -F . 'NF > 1 { print "*." $NF}; NF == 1 { print $NF }' | sort | uniq > exclude.pats
find . -not -name "*.c" -and -not -name "*.h" -and -type f -print0 | xargs -0 basename | grep -E '.*\..+' | sed 's/\./\//g' | xargs basename | xargs printf '*.%s\n' | sort | uniq > X-FILE
chcę wierzyć, że to pomaga, być może także w Linuksie. (W tym przykładzie singiel-name "*.[ch]"
jest w porządku, ale nie jest zbyt ilustracyjny)Możesz także użyć find z -exec, aby wywołać diff:
cd /destination/dir/1 find . -name *.xml -exec diff {} /destination/dir/2/{} \;
źródło
Brak komplementarności - obejmują ....
Możemy zastosować jedno obejście, plik wykluczeń ze wszystkimi plikami, ale to, co chcemy, dołączyć. Więc tworzymy
file1
za pomocą funkcji find wszystkie pliki, które nie mają rozszerzeń, które chcemy uwzględnić,sed
przechwytujemy nazwę pliku i po prostu:Na przykład:
find PATH1/ -type f | grep --text -vP "php$|html$" | sed 's/.*\///' | sort -u > file1 diff PATH1/ PATH2/ -rq -X file1
źródło
find PATH1/ -type f | grep --text -v -e "php$" -e html$" | sed 's/.*\///' | sort -u > file1 diff PATH1/ PATH2/ -rq -X file1
Użyłem następującego polecenia, aby znaleźć różnice wszystkich
*.tmpl
plików międzyDIR1
aDIR2
. W moim przypadku nie przyniosło to żadnych fałszywych alarmów, ale może to być dla Ciebie, w zależności od zawartości Twoich DIRS.diff --brief DIR1 DIR2 | grep tmpl
źródło
Jeśli uznasz to za wygodne, możesz użyć następujących
Makefile
. Po prostu uruchom: „utwórz poprawkę”#Makefile for patches #Exlude following file endings SUFFIX += o SUFFIX += so SUFFIX += exe SUFFIX += pdf SUFFIX += swp #Exlude following folders FOLDER += bin FOLDER += lib FOLDER += Image FOLDER += models OPTIONS = Naur patch: rm test.patch diff -$(OPTIONS) \ $(foreach element, $(SUFFIX) , -x '*.$(element)') \ $(foreach element, $(FOLDER) , -x '$(element)*') \ org/ new/ > test.patch unpatch: rm test.unpatch diff -$(OPTIONS) \ $(foreach element, $(SUFFIX) , -x '*.$(element)') \ $(foreach element, $(FOLDER) , -x '$(element)*') \ new/ org/ > test.unpatch
źródło
Brak komplementarnego - include, sprawia, że konieczne jest stosowanie tak zawiłych wzorców heurystycznych, jak
znaleźć (głównie) pliki java!
źródło
Jeśli chcesz zróżnicować źródła i zachować prostotę:
diff -rqx "*.a" -x "*.o" -x "*.d" ./PATH1 ./PATH2 | grep "\.cpp " | grep "^Files"
Usuń ostatni plik grep, jeśli chcesz pobrać pliki, które istnieją tylko w jednej ze ścieżek.
źródło
Chociaż nie pozwala to uniknąć
diff
innych plików, jeśli Twoim celem jest stworzenie pliku łatki lub podobnego, możesz użyćfilterdiff
zpatchutils
pakietu, np. Do załatania tylko swoich.py
zmian:diff -ruNp /path/1 /path/2 | filterdiff -i "*.py" | tee /path/to/file.patch
źródło