Как использовать команду «cp» для исключения определенного каталога? - PullRequest
353 голосов
/ 03 января 2011

Я хочу скопировать все файлы в каталоге, кроме некоторых файлов в определенном подкаталоге.Я заметил, что команда 'cp' не имеет опции --exclude.Итак, как мне этого добиться?

Ответы [ 18 ]

593 голосов
/ 09 февраля 2013

rsync быстр и прост:

rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude

Вы можете использовать --exclude несколько раз.

rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude --exclude anotherfoldertoexclude

Обратите внимание, что параметр dir thefoldertoexclude после --exclude относится к sourcefolder, т.е. sourcefolder/thefoldertoexclude.

Также вы можете добавить -n для пробного запуска, чтобы увидеть, что будет скопировано перед выполнением реальной операции, и, если все в порядке, удалить -n из командной строки.

74 голосов
/ 11 ноября 2011

Что ж, если исключение определенных шаблонов имен файлов должно выполняться каждой файловой утилитой unix-ish (например, cp, mv, rm, tar, rsync, scp, ...), произойдет огромное дублирование усилий.Вместо этого такие вещи могут быть выполнены как часть globbing , то есть с помощью вашей оболочки.

bash

Ссылка на руководство, поиск extglob .

Пример:

$ shopt -s extglob
$ echo images/*
images/004.bmp images/033.jpg images/1276338351183.jpg images/2252.png
$ echo images/!(*.jpg)
images/004.bmp images/2252.png

Таким образом, вы просто помещаете шаблон внутрь !(), и это сводит на нет совпадение.Шаблон может быть сколь угодно сложным, начиная от перечисления отдельных путей (как Ванварил показывает в другом ответе): !(filename1|path2|etc3), до вещей, похожих на регулярные выражения со звездами и классами персонажей.Подробнее см. На странице справки.

zsh

Ссылка на руководство, раздел «генерация имени файла» .

Вы можетесделать setopt KSH_GLOB и использовать шаблоны, похожие на bash.Или

% setopt EXTENDED_GLOB
% echo images/*
images/004.bmp images/033.jpg images/1276338351183.jpg images/2252.png
% echo images/*~*.jpg
images/004.bmp images/2252.png

Итак x~y соответствует шаблону x, но исключает шаблон y.Еще раз, для полной информации обратитесь к man-странице.


fish new!

Оболочка fish имеет гораздо более симпатичный ответ на этот вопрос:

? cp (string match -v '*.excluded.names' -- srcdir/*) destdir

Бонусный совет

Тип cp *, нажатие Ctrl X * и просто посмотрим, что получится. это не вредно Обещаю

42 голосов
/ 03 января 2011

Зачем использовать rsync, когда вы можете сделать:

find . -type f -not -iname '*/not-from-here/*' -exec cp '{}' '/dest/{}' ';'

Это предполагает, что целевая структура каталогов совпадает с исходной структурой.

32 голосов
/ 19 октября 2012
cp -r `ls -A | grep -v "c"` $HOME/
21 голосов
/ 24 февраля 2014

Самый простой способ, который я нашел, где вы можете скопировать все файлы, кроме файлов и папок, просто добавив их имена в скобках:

shopt -s extglob
cp -r !(Filename1 | FoldernameX | Filename2) Dest/
10 голосов
/ 25 июня 2012

Расширение комментария mvds , это работает для меня

cd dotfiles
tar -c --exclude .git --exclude README . | tar -x -C ~/dotfiles2
8 голосов
/ 28 февраля 2018

Это относительно исходного каталога.
Это исключит копирование каталога source/.git.

rsync -r --exclude '.git' source target
7 голосов
/ 05 апреля 2013

Rsync

rsync -r --verbose --exclude 'exclude_pattern' ./* /to/where/

и сначала попробуйте его с опцией -n, чтобы увидеть, что будет скопировано

7 голосов
/ 03 января 2011

Полагаю, вы используете bash или dash. Будет ли это работать?

shopt -s extglob  # sets extended pattern matching options in the bash shell
cp $(ls -laR !(subdir/file1|file2|subdir2/file3)) destination

Выполнение ls, исключая ненужные файлы, и использование этого в качестве первого аргумента для cp

6 голосов
/ 03 января 2011

Другим более простым вариантом является установка и использование rsync, который имеет опцию --exclude-dir и может использоваться как для локальных, так и для удаленных файлов.

...