Jaki jest najszybszy sposób na przeniesienie miliona obrazów z jednego katalogu do drugiego w systemie Linux?

14

Mam milion zdjęć, które zajmują 30 GB miejsca na dysku, które należy przenieść z jednego katalogu lokalnego do innego katalogu lokalnego.

Jaki byłby najbardziej efektywny sposób to zrobić? Używasz mv? Używasz cp? Używasz rsync? Coś innego?

Muszę wziąć te:

/path/to/old-img-dir/*
                     00000000.jpg
                     --------.jpg  ## nearly 1M of them! ##
                     ZZZZZZZZ.jpg

i przenieś je tutaj:

/path/to/new/img/dir/
Ryan
źródło
5
Nie sądzę, że można pobić pod względem mvwydajności, jeśli katalog źródłowy i docelowy znajdują się w tym samym systemie plików.
Frédéric Hamidi

Odpowiedzi:

26

rsync byłby złym wyborem, ponieważ wykonuje wiele zadań w tle klient / serwer, które dotyczą systemów lokalnych i zdalnych.

mvjest prawdopodobnie najlepszym wyborem. Jeśli to możliwe, powinieneś mv directory_old directory_newraczej spróbować niż mv directory_old/* directory_new/. W ten sposób przesuwasz jedną rzecz zamiast miliona rzeczy.

Richard
źródło
6
+1 za poradę, aby przenieść katalogi zamiast plików.
Ex Umbris,
4
Ponadto rozszerzenie symbolu wieloznacznego prawdopodobnie złamałoby maksymalne argumenty obsługiwane przez, mvjeśli mówimy o milionach.
slhck 16.10.12
6
rsync radzi sobie z transferami na lokalnych nośnikach pamięci. Wymusza takie operacje jak - cały plik (usunięcie implementacji algorytmu delta xfer) i zapobiega innym rzeczom, takim jak - kompresja, która nie służy żadnemu celowi w lokalnych transferach. Jeśli katalogi znajdują się w różnych systemach plików, „mv” nie zapewni żadnej wydajności. Jeśli znajdują się w tym samym systemie plików, to po prostu „mv” katalogi, jak powiedzieli ci ludzie.
UtahJarhead
Jeśli jest wiele obrazów, użycie zwykłej wieloznacznej powłoki spowoduje przepełnienie maksymalnej linii poleceń.
Raúl Salinas-Monteagudo
1
Przechodzenie między dyskami nadal przenosi wszystkie dane. Na tym samym dysku mvaktualizuje tylko informacje imv directory_old directory_newmv directory_old/* directory_new
węzłowe,
14
find src_image_dir/ -type f -name '*.jpg' -print0 | xargs -0r mv -t dst_image_dir/ 
  • Nie spowoduje to przepełnienia interpretacji argumentów.
  • Możesz określić rozszerzenie pliku, jeśli chcesz. (-imię ...)
  • find -print0z xargs -0pozwala używać spacji w nazwach.
  • xargs -rnie uruchomi się, mvchyba że będzie coś do przeniesienia. ( mvnarzeka, jeśli nie podano plików źródłowych).
  • Składnia mv -tpozwala określić najpierw miejsce docelowe, a następnie pliki źródłowe, potrzebne przez xargs.
  • Przenoszenie całego katalogu jest oczywiście znacznie szybsze, ponieważ odbywa się w stałym czasie, niezależnie od liczby zawartych w nim plików, ale:
    • katalog źródłowy zniknie na ułamek czasu i może powodować problemy;
    • jeśli proces używa bieżącego katalogu jako katalogu wyjściowego (w przeciwieństwie do zawsze odwoływania się do pełnej ścieżki z nieruchomej lokalizacji), należy ją ponownie uruchomić. (jak w przypadku rotacji logów ).

Nawiasem mówiąc, zadałbym sobie pytanie, czy naprawdę muszę przenieść tak dużą liczbę plików jednocześnie. Przetwarzanie wsadowe jest przereklamowane. Staram się nie gromadzić ogromnej ilości pracy, jeśli potrafię przetwarzać rzeczy w momencie ich wygenerowania.

Raúl Salinas-Monteagudo
źródło
Działa to wystarczająco dobrze, aby przenosić pliki między systemami plików na tym samym serwerze. Na tyle, że nie zawracałem sobie głowy szukaniem rozwiązania w rsync. Pewnie, że zajęło to godzinę lub dwie, ale działa. Warto zwrócić uwagę, jeśli podasz nazwę katalogu zamiast „.” - pamiętaj, aby użyć końcowego ukośnika w poleceniu find, w przeciwnym razie katalog zostanie odtworzony w miejscu docelowym polecenia mv.
Speeddymon
7

Jeśli dwa katalogi znajdują się w tym samym systemie plików, użyj mvkatalogu DIRECTORY, a nie zawartości katalogu.

Jeśli rezydują w dwóch różnych systemach plików, użyj rsync:

rsync -av /source/directory/ /destination

Zwróć uwagę na końcowe /źródło. Oznacza to, że skopiuje ZAWARTOŚĆ katalogu, a nie sam katalog. Jeśli wyłączysz /, nadal będzie kopiować pliki, ale będą one znajdować się w katalogu o nazwie /destination/directory. Z /, pliki będą po prostu w/destination

rsynczachowa własność pliku, jeśli uruchomisz go jako root lub jeśli pliki są Twoją własnością. Będzie także utrzymywać mtimekażdy pojedynczy plik.

Utah Jarhead
źródło
2
rsyncWydaje się , że do kopiowania dużego folderu z jednego dysku twardego na inny dysk twardy krąży wokół mv. Dzięki za wskazówkę!
Leo-the-manic
2
tar cf - dir1 | (cd dir2; tar xf -)

tar cf - dir1 | ssh remote_host "( cd /path/to/dir2; tar xf - )"

Kiedy używasz „cp”, każdy plik wykonuje polecenie otwórz-przeczytaj-zamknij-otwórz-zapisz-zamknij. Tar używa różnych procesów do odczytu i zapisu, a także wielu stopni do obsługi wielu plików jednocześnie. Nawet w przypadku pojedynczego procesora aplikacje wielowątkowe są szybsze.

maholt
źródło
2
Chociaż może to odpowiedzieć na pytanie, lepszym rozwiązaniem byłoby podanie wyjaśnienia, dlaczego tak się dzieje.
DavidPostill
1
Jeśli znajdują się na komputerze lokalnym, prawdopodobnie znajdują się w tym samym systemie plików. Korzystając z niej tar c | tar x, otrzymasz koszt O (całkowity rozmiar) zamiast O (liczba_plików).
Raúl Salinas-Monteagudo
1

Ponieważ zarówno katalog_główny, jak i nowy katalog znajdują się w tym samym systemie plików, którego można użyć cp -lzamiast mvjako opcji. cp -lutworzy twarde linki do oryginalnych plików. Kiedy skończysz z 'move' i będziesz zadowolony z rezultatu, możesz usunąć te pliki z katalogu_older. jeśli chodzi o szybkość, będzie on taki sam jak „mv”, ponieważ najpierw tworzysz linki, a następnie usuwasz oryginalne. Ale to podejście pozwala zacząć od początku, jeśli ma to sens

Serge
źródło
0

To zależy (tm). Jeśli twój system plików to kopiowanie przy zapisie, wówczas kopiowanie ( cplub rsync, na przykład) powinno być porównywalne z przeniesieniem. Ale w najczęstszych przypadkach move ( mv) będzie najszybszy, ponieważ może po prostu przełączać fragmenty danych opisujące miejsce umieszczenia pliku (uwaga: jest to zbyt uproszczone).

Tak więc, przy przeciętnej instalacji Linuksa, wybrałbym mv.

EDYCJA: @ Frédéric Hamidi ma rację w komentarzach: Jest to poprawne tylko wtedy, gdy oba są na tym samym systemie plików i dysku. W przeciwnym razie dane i tak zostaną skopiowane.

Carlpett
źródło
0

Aby skopiować co najmniej ~ 10 000 plików (bez katalogów), cp narzekał:

nie można wykonać / bin / cp: lista argumentów za długa

Najlepszą opcją jest Rsync:

cel źródłowy rsync

I zrobiono to bardzo szybko!

Nico
źródło
0

Jeśli masz wolne miejsce, zarchiwizuj je w jednym pliku .tar (bez kompresji jest szybszy), a następnie przenieś ten plik i zarchiwizuj go.

endolit
źródło
0

Charakter miejsca docelowego określałby najbardziej efektywny sposób wykonania tego zadania. Załóżmy, że jesteś na systemie lokalnym, twój PWDjest /teraz. i /azawiera miliony zdjęć. Naszym zadaniem jest przeniesienie wszystkich obrazów /bprzy zachowaniu całej struktury podkatalogów. Załóżmy również /ai /bsą punktami montowania dla dwóch różnych partycji, każda na dysku podłączonym lokalnie. Chcielibyśmy wykonać to zadanie za pomocą plandeki. Może to zająć trochę czasu, więc upewnij się, że używasz screen, tmuxlub wykonać to jako proces w tle.

tar -C /a -cf . | tar -C /b -xf -

To by skopiować wszystkie pliki i katalogi w /acelu /b, więc teraz trzeba posprzątać /apo potwierdzić to zakończone bez błędu.

JM Becker
źródło