Mam miliony plików z następującą nomenklaturą na komputerze z systemem Linux:
1559704165_a1ac6f55fef555ee.jpg
Pierwsze 10 cyfr to znacznik czasu, a następujące po nich _
to konkretne identyfikatory. Chcę przenieść wszystkie pliki pasujące do określonych identyfikatorów plików do innego folderu.
Próbowałem tego w katalogu z plikami
find . -maxdepth 1 -type f | ??????????_a1ac*.jpg |xargs mv -t "/home/ubuntu/ntest"
Jednak pojawia się błąd wskazujący:
bash 1559704165_a1ac6f55fef555ee.jpg: command not found
Kiedy próbowałem, mv ??????????_a1ac*.jpg
pojawia się zbyt długi błąd listy argumentów. Mam co najmniej 15 różnych wzorów nazw plików. Jak je przenieść?
| ??????????_a1ac*.jpg
: bash rozwija ją do kilku nazw plików, pierwszą rzeczą jest to1559704165_a1ac6f55fef555ee.jpg
, że skończysz , w tym drugim etapie potoku, próbując wykonać:1559704165_a1ac6f55fef555ee.jpg next_matching_filename 3rd_matching_filename ... nth_matching_filename
Myślę, że zamiast tego próbowałeś przefiltrować do tej nazwy pliku (zobacz odpowiedzi poniżej)Odpowiedzi:
Powinieneś użyć:
Tak więc
maxdepth 1
środki, które chcesz wyszukać w bieżącym katalogu bez podkatalogów.type f
oznacza znajdź tylko pliki.name '??????????_a1ac*.jpg'
to wzorzec pasujący do szukanego pliku.mv -t destination "{}" +
oznacza przeniesienie dopasowanych plików do miejsca docelowego. Tutaj+
dodaje nowe dopasowane pliki do poprzedniego, takie jak:Tutaj abcd to różne pliki.
źródło
-t
jest to rozszerzenie GNU, więc może nie być dostępne w innych typach pochodnych UNIX."{}"
, w którym to przypadku chcę podkreślić, że{}
nie jest on rozszerzany przez powłokę i nie trzeba go cytować. Powłoka przechodzi,{}
by znaleźć i znaleźć, widzi{}
i zastępuje ją ścieżkami. Find exec nie używa parsera powłoki i nie dokonuje własnego podziału słów. Cytując, nie wyrządza to żadnej szkody, po prostu podane uzasadnienie jest nieco niedokładne.Twoje rozkaz
Przerzuca listę wszystkich plików DO wszystkich plików!
da rade.
źródło
Jesteś bardzo blisko. Powinieneś użyć
-name
opcji dofind
. I pamiętaj, aby zacytować wzór.Więc
źródło
-print0
jako ostatni argument do find (zamiast domyślnego: -print) i dodać-0
jako pierwszą opcję do xargs (tjxargs -0 mv -t "/home/ubuntu/ntest"
. :) . w ten sposób można obsłużyć wszelkiego rodzaju dziwne nazwy plików (ze spacjami, „newline” itp.).find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' -print0 |xargs -0 mv -t "/home/ubuntu/ntest"
(działa tylko z znalezieniem podobnym do GNU)Nie tak „dobre” jak
find
rozwiązania, ale innym prawidłowym rozwiązaniem jestmv
zwiększenie szczegółowości poleceń.Robi to 4096 ruchów, przy mniejszej liczbie plików przenoszonych na
mv
operację.źródło
find
(z jakiegokolwiek powodu).Jeśli chcesz przenieść pliki na ten sam system hosta, co, jak sądzę, robisz ze swoim
mv
,rsync
może być szybszą opcją:--inplace
i-W
są ustawione na przyspieszenie procesu.Jeśli to spowoduje, że kolejny argument listy będzie zbyt długi, możesz podać listę
rsync
Utwórz listę za pomocą na przykład find
i daj to
rsync
Oto źródło
/path/to/files
, ponieważrsync
potraktuje podaną przez ciebie listę w stosunku do twojego źródła.Chodzi o to, że:
rsync
jest szybszy niżmv
, jeśli pliki nie są w tym samym systemie plików .źródło
find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' > /tmp/my_image_list.txt
A następnie przekazać ją do rsync--files-from=/tmp/my_image_list.txt
. Chodzi o to, żersync
jest szybszy. Chyba że pliki znajdują się w tym samym systemie plików, czego OP nie wskazał.