Как вы можете переместить (или скопировать) все файлы определенного типа в каталог в Unix?

22

Я пока не очень знаком со всеми хитростями grep/find/awk/xargs.

Скажем, у меня есть файлы, соответствующие определенному шаблону *.xxx. Эти файлы находятся в случайных местах в определенном каталоге. Как я могу найти все такие файлы и переместить их в папку в моем домашнем каталоге в Unix (которая может еще не существовать)?

qodeninja
источник
4
Вы должны быть осторожны, когда говорите о «типе файла». В среде Unixy пример «.xxx» даже не является расширением в смысле Windows. «.xxx» просто представляет собой суффикс имени файла. «Тип файла» - это еще одна из нескольких категорий: обычный файл, файл устройства, символическая ссылка, каталог, именованный канал, сокет семейства Unix и, возможно, несколько других.
Брюс Эдигер
1
Смотрите также: unix.stackexchange.com/questions/7027/…
jasonwryan
@BruceEdiger спасибо, наверное, я действительно имел в виду «шаблон имени файла»
qodeninja

Ответы:

22
mkdir ~/dst
find source -name "*.xxx" -exec mv -i {} -t ~/dst \;
Kevin
источник
1
Я бы использовалmv -i -t ~/dst {} +
enzotib
17

Если вы хотите переместить все файлы в иерархии каталогов в один каталог назначения, в bash ≥4 (вставьте shopt -s globstarв свой ~/.bashrc) или zsh:

mkdir ~/new-directory
mv -i **/*.xxx ~/new-directory

В других оболочках:

mkdir ~/new-directory
find . -name '*.xxx' -exec mv -i {} ~/new-directory \;

Как читать эту findкоманду:

  • .: пройти текущий каталог
  • -name '*.xxx': действовать на файлы, имя которых соответствует этому шаблону
  • -exec … \;: выполнить эту команду для каждого файла, заменив {}путь к файлу

Существует более сложная команда, использующая findэто быстрее, если у вас много файлов, так как не нужно вызывать отдельный mvпроцесс для каждого файла:

find . -name '*.xxx' -exec sh -c 'mv -i "$@" "$0"' ~/new-directory {} +

В +конце указывается findвызывать команду для нескольких файлов одновременно. Так findкак имена файлов можно помещать только в конец командной строки, а mvкаталог назначения должен быть последним, мы используем промежуточную оболочку для перестановки аргументов ( "$0"это первый аргумент оболочки ~/new-directoryи "$@"последующие аргументы, поступающие из findэкспансия {}).

Жиль "ТАК - перестань быть злым"
источник
4

Если вы хотите скопировать структуру каталогов соответствующих исходных файлов в новый целевой каталог, вы можете использовать опцию --parents GNU cp :

mkdir /path/to/target_dir
cd source_dir
find . -name '*.xxx' -exec cp -iv --parents -t /path/to/target_dir {} +
frielp
источник
3

Вы можете использовать находку без , а-exec‍ также:

mkdir /path/to/dest    
cp `find /path/to/source -name "*.jar"` /path/to/dest
Кен Зейн
источник
1
Обратите внимание, что find -execэто гораздо безопаснее; Например, вышеописанное не будет работать с именами файлов, содержащими пробелы.
дхаг