Jak wyszukiwać pliki we wszystkich podkatalogach za pomocą powłoki, a następnie kopiować te pliki?

8

Jak mogę znaleźć tylko pliki * .mp3 za pomocą polecenia rekurencyjnego, np. ls -R *.mp3W katalogu zawierającym kilka podkatalogów, a na koniec skopiować te pliki do wybranego przeze mnie katalogu.

Dziękuję za wsparcie.

V 3 L 3 N 0
źródło

Odpowiedzi:

14

Polecenie to:

find /path/to/directory -name "*.mp3" -exec cp {} /some/other/dir/ \;

Alternatywny:

find /path/to/dir/ -name '*.mp3' | xargs cp -t /target/

Przykład:

alex@MaD-pc:~/test$ ls
1  2  3
alex@MaD-pc:~/test$ ls 1 2 3
1:
1.txt  2.mp3  3.txt

2:
4.txt  5.mp3  6.txt

3:
alex@MaD-pc:~/test$ find . -name "*.mp3" -exec cp {} 3/ \;
alex@MaD-pc:~/test$ ls 3
2.mp3  5.mp3

Po więcej informacji:

man find
hytromo
źródło
Sędziowie przyjęliby również:find /path/to/dir/ -name '*.c' | xargs cp -t /target/
Oli
Jestem jednym z sędziów i zaprzeczam temu rozwiązaniu 8-) Dzięki za komentarz, dodam go :)
hytromo
1
xargsjest zwykle znacznie szybszy. Właśnie uruchomiłem szybki test, znajdując ładunek plików c i uruchomiłem ls -lje. Jest 0m2.420s dla xargsi 0m25.494s dla -exec... Oczywiście w tym przypadku cpoperacja zajmie większość czasu, więc prawdopodobnie nie ma to znaczenia, ale warto o tym pamiętać.
Oli
-n`` switch to the Poleciłbym dodanie polecenia cp`, aby uniknąć zastąpienia w przypadku zduplikowanych nazw (lub napisanie skryptu, który sprawdza duplikaty przed skopiowaniem i w razie potrzeby zmianę nazwy celu)
Starszy Geek
2

Jest też inny sposób, aby to zrobić, który moim zdaniem będzie idealnie pasował do twojego celu. Można łączyć findz whilepętli i nawet nie trzeba użyć jednej z execlub xargsw ogóle. Jeśli na przykład chcesz skopiować swój mp3sfolder z folderu pobierania do folderu z muzyką, skorzystaj z następującego skryptu, z którego korzystałem wiele razy.

Możesz go zmodyfikować, jak chcesz, zmieniając katalogi, które findwyszukują i umieszczają pliki wynikowe; jeśli nie podano żadnego katalogu, findprzeszuka cały folder domowy. Możesz także zmienić cpna mvlub inne polecenia. Jest dość szybki, ponieważ właśnie przetestowałem go z 3945 .jpgplikami! Skopiuj go do edytora tekstowego, zapisz, a następnie uruchom go, uruchamiając chmod +x myscript.

#!/bin/bash
# a script to recursively find and copy files to a desired location
find ~/Downloads -type f -iname '*.mp3' -print0 |
while IFS= read -r -d '' f; 
do cp -- "$f" ~/Music ;
done

Na tej zauważonej wiki Bash pokazano, jak przydatne jest połączenie whilepętli i readpoleceń w celu przetworzenia wyniku findpolecenia; a sposób, w jaki to zrobiłem, zapewnia, że ​​skrypt nie ulegnie awarii, jeśli natrafi na nazwy plików ze spacjami lub innymi nieoczekiwanymi lub specjalnymi znakami.

Aby uzyskać bardziej ogólne informacje na temat findpolecenia, wpisz w terminalu man findlub zobacz strony Ubuntu online . Świetne wprowadzenie do użycia funkcji find znajduje się również w tym artykule .


źródło
nie jest find ~/Downloads -type f -iname '*.mp3' | while read mp3file; do cp "$mp3file" ~/Music; doneprostsze?
steabert
Moja metoda stanowi najlepszą praktykę i zapobiega uszkodzeniu skryptu, jak zauważono w cytowanym przeze mnie linku.
ah, rozumiem, że zajmuje się obsługą znaków specjalnych, dzięki za link :)
steabert
-n`` switch to the Poleciłbym dodanie polecenia cp`, aby uniknąć zastąpienia w przypadku zduplikowanych nazw (lub napisanie skryptu, który sprawdza duplikaty przed skopiowaniem i w razie potrzeby zmianę nazwy celu)
Starszy Geek