Я хочу скопировать все файлы в каталог, кроме некоторых файлов в определенном подкаталоге. Я заметил, что команда "cp" не имеет опции -exclude. Итак, как я могу достичь этого?
Как использовать команду "cp" для исключения определенного каталога?
Ответ 1
rsync быстрый и простой:
rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude
Ответ 2
Хорошо, если исключение определенных шаблонов имен файлов должно выполняться каждой утилитой 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)
, для регулярных выражений со звездами и классами символов. Подробнее см. В man-странице.
ЗШ
Ссылка в руководство, раздел "генерация имени файла" .
Вы можете сделать 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
. Еще раз, для получения полной информации обратитесь к manpage.
Бонус-подсказка
Введите cp *
, нажмите Ctrl X * и просто посмотрите, что произойдет. это не вредно Я обещаю
Ответ 3
Зачем использовать rsync
, когда вы можете:
find . -type f -not -iname '*/not-from-here/*' -exec cp '{}' '/dest/{}' ';'
Предполагается, что структура целевой директории совпадает с исходной.
Ответ 4
cp -r `ls -A | grep -v "c"` $HOME/
Ответ 5
Самый простой способ найти, где вы можете скопировать все файлы, исключая файлы и папки, просто добавив их имена в круглые скобки:
cp -r !(Filename1 | FoldernameX | Filename2) Dest/
Ответ 6
Я предполагаю, что вы используете bash или тире. Будет ли это работать?
shopt -s extglob # sets extended pattern matching options in the bash shell
cp $(ls -laR !(subdir/file1|file2|subdir2/file3)) destination
Выполнение ls, исключая файлы, которые вы не хотите, и используя это как первый аргумент для cp
Ответ 7
Развернувшись на комментарий mvdss, это работает для меня
cd dotfiles
tar -c --exclude .git --exclude README . | tar -x -C ~/dotfiles2
Ответ 8
Другим более простым вариантом является установка и использование rsync, который имеет параметр --exclude-dir, и может использоваться как для локальных, так и для удаленных файлов.
Ответ 9
Rsync
rsync -r --verbose --exclude 'exclude_pattern' ./* /to/where/
и попробуйте сначала с параметром -n, чтобы увидеть, что будет скопировано
Ответ 10
Это модификация ответа Линуса Клеена. Его ответ не сработал у меня, потому что будет. добавлен перед файловым трактом, который cp не нравится (путь будет выглядеть как источник /.destination/file).
Эта команда работала для меня:
find . -type f -not -path '*/exlude-path/*' -exec cp --parents '{}' '/destination/' \;
команда -parents сохраняет структуру каталогов.
Ответ 11
mv tobecopied/tobeexcluded .
cp -r tobecopied dest/
mv tobeexcluded tobecopied/
Ответ 12
Просто переместите его временно в скрытый каталог (и переименуйте его после, если хотите).
mkdir .hiddendir
cp * .hiddendir -R
mv .hiddendir realdirname
Ответ 13
Один из способов - использовать find -0
с -prune
, чтобы найти все файлы и каталоги, которые вы хотите переместить, а затем использовать xargs -0
для копирования каждого из них.
Ответ 14
cp -rv `ls -A | grep -vE "dirToExclude|targetDir"` targetDir
Изменить: забыл также исключить целевой путь (иначе он будет рекурсивно скопировать).
Ответ 15
Я использую цикл "do while" для чтения вывода команды find. В этом примере я сопоставляю (а не исключая) определенные шаблоны, так как существует более ограниченное количество совпадений шаблонов, которые я хочу, чем того, чего я не хочу. Вы можете изменить логику с помощью -not перед -in-flags:
find . -type f -iname "*.flac" -o -print0 -iname "*.mp3" -print0 -o -iname "*.wav" -print0 -o -iname "*.aac" -print0 -o -iname "*.wma" -print0 | while read -d $'\0' file; do cp -ruv "$file" "/media/wd/network_sync/music/$file"; done
Я использую приведенное выше, чтобы скопировать все файлы музыкального типа, которые являются более новыми на моем сервере, чем файлы в живом концентраторе Western Digital TV Live, который я установил на /media/wd. Я использую вышеуказанное, потому что у меня много файлов DVD, mpeg и т.д., Которые я хочу исключить. И поскольку по какой-то причине rsync выглядит так, как будто это копирование, но после того, как я посмотрю на wd-устройство, файлов там нет, ошибки во время rsync с помощью этой команды:
rsync -av --progress --exclude=*.VOB --exclude=*.avi --exclude=*.mkv --exclude=*.ts --exclude=*.mpg --exclude=*.iso --exclude=*ar --exclude=*.vob --exclude=*.BUP --exclude=*.cdi --exclude=*.ISO --exclude=*.shn --exclude=*.MPG --exclude=*.AVI --exclude=*.DAT --exclude=*.img --exclude=*.nrg --exclude=*.cdr --exclude=*.bin --exclude=*.MOV --exclude=*.goutputs* --exclude=*.flv --exclude=*.mov --exclude=*.m2ts --exclude=*.cdg --exclude=*.IFO --exclude=*.asf --exclude=*.ite /media/2TB\ Data/data/music/* /media/wd/network_sync/music/