Mam dwa katalogi z tysiącami plików, które zawierają mniej więcej te same pliki.
Jak mogę skopiować wszystkie pliki z katalogu dirA do katalogu dirB, które nie znajdują się w katalogu dirB lub jeśli plik istnieje w katalogu dirB, nadpisuje go tylko wtedy, gdy jest mniejszy.
Wiem, że istnieje wiele przykładów różnych znaczników czasu lub różnych rozmiarów plików, ale chcę je zastąpić tylko wtedy, gdy plik docelowy jest mniejszy i w żadnym wypadku nie jest większy.
Tło mojego problemu:
Wyrenderowałem dynmapę na moim serwerze Minecraft, ale niektórych kafelków brakuje lub są one uszkodzone. Następnie wykonałem renderowanie ponownie na innym komputerze z szybszym procesorem i skopiowałem wszystkie nowe renderowane pliki (~ 50 GB / 6.000.000 ~ 4-10 KB PNG) na mój serwer. Potem zauważyłem, że w moim nowym renderowaniu są również uszkodzone pliki.
left: stary render, prawo: nowy render
Dlatego nie chcę nadpisywać wszystkich plików, ale tylko te, które są większe (uszkodzone przenoszą mniej danych i są mniejsze).
źródło
cp
z kombinacjącmp
poleceń lub lepiej korzystaj zrsync
wszystkich dostępnych opcjistat
na plikach w obu lokalizacjach, aby uzyskać rozmiar pliku, a następnie skopiuj, jeśli spełnia twoje warunkirsync
opcji, których potrzebujesz, ale nie znalazłem właściwej, więc poszedłem w prosty sposóbOdpowiedzi:
Może to brudny sposób, ale mam nadzieję, że tego właśnie szukasz
źródło
ls argument list too long
)getconf ARG_MAX
:). Prawdopodobnie masz tam dość długie nazwy plików lub bardzo głęboką strukturę katalogów, więc przyfind
podawaniuls
takich nazw przekracza maksymalną dozwoloną długość dla wiersza poleceń. Zmodyfikowałem mały skrypt, aby wyeliminowaćls
polecenie, możesz wypróbować tę nową wersję.sudo mkdir -m 777 /a
następnie zamontuj katalog źródłowy,/a
tak jaksudo mount --bind /pretty/long/prefix/to/source/directory /a
wtedy użyj/a
w moim skrypcie. Po zakończeniu odmontuj/a
według polecenia wydania:sudo umount /a
diff --brief -r dir1/ dir2/
dobrym podejściem, a następnie zrób coś dla każdego wiersza wyniku. Spróbuję wieczorem zbudować coś takiego.Możesz użyć polecenia rsync
Składnia:
rsync -avz --progress <source path> <destination path>
możesz użyć
--delete
do usunięcia obcych plików z katalogu docelowegorsync -avz --delete --progress <source path> <destination path>
więc twoje polecenie będzie:
źródło
Mój problem był podobny. Chciałem zsynchronizować pliki z folderu zdalnego do lokalnego, ale skopiuj tylko pliki zdalne, które były większe niż odpowiednie pliki lokalne.
Moje obejście z rsync było takie, co w rzeczywistości było jednoznaczne:
Myślę, że można zrozumieć, ponieważ nazwy plików są takie same między dwoma folderami, przeglądam każdy z nich w folderze lokalnym i zachowuję jego rozmiar, a następnie ustalam, czy rsync powinien kopiować, czy nie, plik zdalny ta sama nazwa, ale inny rozmiar.
źródło
ls
ten sposób; po prostu zróbfor x in home/me/local/folder/*
.Zmodyfikowałem to do czegoś takiego:
Następnie napisałem inną metodę dostosowania plików, które chcę skopiować, i podaję je do funkcji copy_if_larger.
źródło