Как я могу искать файлы во всех подкаталогах, используя оболочку, а затем копировать эти файлы?

8

Как найти только файлы * .mp3 с помощью рекурсивной команды, например, ls -R *.mp3в каталоге, который содержит несколько подкаталогов, и в конце скопировать эти файлы в каталог, который я выбрал.

Спасибо за вашу поддержку.

V 3 L 3 N 0
источник

Ответы:

14

Команда:

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

Альтернатива:

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

Пример:

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

За дополнительной информацией:

man find
hytromo
источник
Судьи также примут:find /path/to/dir/ -name '*.c' | xargs cp -t /target/
Оли
Я один из судей, и я отрицаю это решение 8-) Спасибо за комментарий, я добавлю его :)
hytromo
1
xargsкак правило, намного быстрее. Я только что провел быстрый тест, чтобы найти загрузку файлов c и запустить ls -lих. Это 0m2.420s для xargsи 0m25.494s для -exec... Очевидно, что в этом случае cpоперация займет большую часть времени, так что, вероятно, это не имеет значения, но стоит помнить.
Оли
Я бы порекомендовал добавить команду -n`` switch to the cp`, чтобы избежать перезаписи в случае дублирования имен (или написания скрипта, который проверяет наличие дубликатов перед копированием и переименовывает цель при необходимости)
Elder Geek
2

Есть и другой способ сделать это, который, я думаю, будет соответствовать вашим целям. Вы можете комбинировать findс whileциклом и даже не нужно использовать или из execили xargsвообще. Если, например, вы хотите скопировать mp3sсвою папку загрузки в свою папку музыки, вы должны использовать следующий скрипт, который я использовал много раз.

Вы можете изменить его так, как вы хотите, изменив каталоги, в которых производится findпоиск и размещение полученных файлов; если каталог не указан, findбудет искать всю домашнюю папку. Вы также можете изменить cpк mvили другим командам. Это довольно быстро, так как я только что проверил это с 3945 .jpgфайлами! Скопируйте его в текстовый редактор, сохраните его, а затем сделайте его исполняемым 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

На этой отмеченной вики Bash показано, насколько полезно комбинировать whileцикл и readкоманды для обработки выходных данных findкоманды; и способ, которым я это сделал, гарантирует, что скрипт не сломается, если он встретит имена файлов с пробелами или другими неожиданными или специальными символами.

Для получения более общей информации о findкоманде введите в терминале man findили посмотрите онлайн- руководства по Ubuntu . Прекрасное введение в использование find см. Также в этой статье .


источник
не find ~/Downloads -type f -iname '*.mp3' | while read mp3file; do cp "$mp3file" ~/Music; doneпроще?
Steabert
Мой метод представляет лучшую практику и предотвращает взлом скрипта, как отмечено в ссылке, которую я цитировал.
ах, я вижу, это заботится об обработке специальных символов, спасибо за ссылку :)
steabert
Я бы порекомендовал добавить команду -n`` switch to the cp`, чтобы избежать перезаписи в случае дублирования имен (или написания скрипта, который проверяет наличие дубликатов перед копированием и переименовывает цель при необходимости)
Elder Geek