Mam katalog zawierający około 280 000 plików. Chcę przenieść je do innego katalogu.
Jeśli użyję cp
lub mv
dostanę błąd, „lista argumentów jest za długa”.
Jeśli napiszę skrypt
for file in ls *; do
cp {source} to {destination}
done
następnie, z powodu ls
polecenia, jego wydajność spada.
Jak mogę to zrobić?
linux
file-management
potrójny
źródło
źródło
tar
te pliki?Odpowiedzi:
Użyj rsync :
na przykład
(zwróć uwagę na końcowe)
Uwaga: jeśli jest to długa operacja i chcesz zobaczyć pewne informacje o postępie podczas kopiowania, możesz dodać
-v
opcję (verbose), która następnie wyświetla listę wszystkich kopiowanych plików, lub rozważyć użycie tej--progress
opcji, aby uzyskać bardziej zwięzły wynik.źródło
rsync -a /some/path/src/ /other/path/to/
- zwróć uwagę na końcowe / s.W odpowiedziach brakuje mi dwóch wahań, więc dodaję jeszcze jeden.
Chociaż przypomina mi to dodanie kolejnej
standardowejodpowiedzi ...Istnieją tutaj dwa problemy:
Większość narzędzi nie skaluje się tak dobrze przy tej liczbie plików. Nie tylko większość narzędzi Linuksa lub Windows, ale sporo programów. I może to obejmować twój system plików. Długoterminowym rozwiązaniem byłoby „dobrze, nie rób tego wtedy”. Jeśli masz różne pliki, ale w różnych katalogach. Jeśli nie, możesz spodziewać się kolejnych problemów.
Powiedziawszy to, przejdźmy do rzeczywistego problemu:
Jest to spowodowane rozszerzeniem * przez powłokę. Powłoka ma ograniczone miejsce na wynik i kończy się. Oznacza to, że każde polecenie z
*
rozszerzeniem przez powłokę napotka ten sam problem. Będziesz musiał albo rozwinąć mniej opcji w tym samym czasie, albo użyć innego polecenia.Jednym z nich jest często używane alternatywne polecenie
find
. Jest już kilka odpowiedzi pokazujących, jak z niego korzystać, więc nie zamierzam tego wszystkiego powtarzać. Zwrócę jednak uwagę na różnicę między,\;
a+
ponieważ może to mieć ogromną różnicę w wydajności i ładnie przyłączyć się do poprzedniego wyjaśnienia dotyczącego rozszerzenia.find /path/to/search --name "*.txt" -exec command {} \;
Znajduje wszystkie pliki w ścieżce / to / search / i wykonuje z nim polecenie, ale zwraca uwagę na cudzysłów wokół
*
. To podaje * do polecenia. Gdybyśmy go nie zamknęli ani nie uciekli, powłoka spróbowałaby go rozwinąć i otrzymalibyśmy ten sam błąd.Na koniec chcę wspomnieć o {}. Te nawiasy zastępowane są treścią znalezioną przez find. Jeśli zakończysz polecenie średnikiem
;
(takim, który musisz uciec z powłoki, stąd\;
w przykładach), wówczas wyniki są przekazywane jeden po drugim. Oznacza to, że wykonasz komendy 280000 mv. Jeden na każdy plik. To może być powolne.Alternatywnie możesz zakończyć
+
. To przekaże jak najwięcej argumentów jednocześnie. Jeśli bash może obsłużyć 2000 argumentów, to find / path -name "* filetype" -exec some_move {} + wywoła komendę some_move około 140 razy, za każdym razem z 2000 argumentami. To jest bardziej wydajne (czytaj: szybciej).źródło
Nie potrzebujesz ls, możesz po prostu użyć
lub możesz zrobić coś takiego:
źródło
"$file"
pętli.źródło
Zakładając, że chcesz przenieść pliki w tym samym systemie plików, możesz po prostu zmienić nazwę katalogu zawierającego twoje LACS i gotowe.
źródło
Lubię
rsync
to lub:źródło
Co powiesz na przenoszenie (zamiast kopiowania):
Myślę, że to się zmieni, zachowując strukturę (podkatalogi) i ukryte pliki lub katalogi, a także nie zajmując dodatkowego miejsca, jak w przypadku rsync + rm. A jeśli {origin} i {destination} są na tej samej partycji, będzie szybciej.
źródło
Używanie tar:
Działa, aby zacząć wszystko, gdy początkowo początkowo jest za duże dla rsync, ale delta nie są.
źródło
W moim przypadku, zarówno
cp
irsync
były zbyt powolne kopiowanie około 4 milionów plików z HDD na SSD, więc oto jak poszedłem o tym (wszystkie moje pliki były .txt pliki w tym samym folderze, więc dostosowaćfind
do potrzeb klienta):Musiałem wydrukować nazwy plików do pliku tymczasowego, ponieważ trafiłem w
Argument list too long
błąd. Używająctar
znacznie poprawionych moich prędkości przesyłania, chociaż mogę założyć, że pliki, które są trudniej skompresowane, mogą nie działać tak dobrze.źródło