Как использовать команду " cp " для исключения определенного каталога?
Я хочу скопировать все файлы в каталог, кроме некоторых файлов в определенном подкаталоге. Я заметил, что команда " cp " не имела опции --exclude. Итак, как я могу достичь этого?
17 ответов
rsync быстро и легко:
rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude
можно использовать --exclude
кратно раз.
также вы можете добавить -n
для сухого запуска, чтобы увидеть, что будет скопировано перед выполнением реальной операции, и если все в порядке, удалите -n
из командной строки.
Ну, если исключение определенных шаблонов файлов должно было выполняться каждой утилитой файлов unix-ish (например, cp, mv, rm, tar, rsync, scp,...), произойдет огромное дублирование усилий. Вместо этого, такие вещи могут быть сделаны как часть подстановка, то есть вашей оболочкой.
Баш
ссылке в ручную, поиск 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)
, чтобы regex-подобные вещи со звездами и классами символов. См. manpage для деталей.
ЗШ
ссылке в руководстве, раздел "генерация имени файла".
можно сделать 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
. Еще раз, для полной информации обратитесь к странице помощи.
рыбноеновый!
на рыбное shell имеет гораздо красивее ответ для этого:
cp (string match -v '*.excluded.names' -- srcdir/*) destdir
бонус pro-tip
тип cp *
, нажмите CtrlX* и просто посмотреть, что происходит. это не вредно обещаю
зачем использовать rsync
когда вы можете сделать:
find . -type f -not -iname '*/not-from-here/*' -exec cp '{}' '/dest/{}' ';'
предполагается, что целевая структура каталогов совпадает с исходной.
самый простой способ, который я нашел, где вы можете скопировать все файлы, исключая файлы и папки, просто добавив их имена в скобках:
cp -r !(Filename1 | FoldernameX | Filename2) Dest/
Я предполагаю, что вы используете 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
расширения комментарий mvds, это работает для меня
cd dotfiles
tar -c --exclude .git --exclude README . | tar -x -C ~/dotfiles2
другой более простой вариант-установить и использовать rsync, который имеет параметр --exclude-dir и может использоваться как для локальных, так и для удаленных файлов.
rsync
rsync -r --verbose --exclude 'exclude_pattern' ./* /to/where/
и сначала попробуйте с опцией-n, чтобы увидеть, что будет скопировано
Это модификация ответа Лайнуса Клина. Его ответ не сработал для меня, потому что был бы . добавлен перед путем файла, который не нравится cp (путь будет выглядеть как source/.файл назначения.)
эта команда сработала для меня:
find . -type f -not -path '*/exlude-path/*' -exec cp --parents '{}' '/destination/' \;
команда --parents сохраняет структуру каталогов.
это относительно исходного каталога.
Это исключит каталог source/.git
копировать.
rsync -r --exclude '.git' source target
просто переместите его временно в скрытый каталог (и переименуйте его после, если хотите).
mkdir .hiddendir
cp * .hiddendir -R
mv .hiddendir realdirname
один из способов-использовать find -0
с -prune
найти все файлы и каталоги, которые вы хотите переместить, а затем использовать xargs -0
скопировать каждый.
cp -rv `ls -A | grep -vE "dirToExclude|targetDir"` targetDir
Edit: забыл исключить целевой путь (в противном случае он будет рекурсивно копировать).
Я использую цикл "do while" для чтения вывода команды find. В этом примере я сопоставляю (а не исключаю) определенные шаблоны, поскольку есть более ограниченное количество совпадений шаблонов, которые я хочу, чем то, что я не хочу. Вы можете изменить логику с помощью a-not перед флагами-iname:
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 $'' file; do cp -ruv "$file" "/media/wd/network_sync/music/$file"; done
Я использую выше, чтобы скопировать все файлы типа музыки, которые новее на моем сервере, чем файлы на Western Digital TV Live Hub, который я установил в /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/
rsync
на самом деле довольно сложно. нужно сделать несколько тестов, чтобы это сработало.
Допустим, вы хотите скопировать /var/www/html
to /var/www/dev
а нужно исключить /var/www/html/site/video/
каталог, возможно, из-за его размера. Команда будет:
rsync -av --exclude 'sites/video' /var/www/html/ /var/www/dev
некоторые предостережение:
- последняя черта
/
в источнике необходимо, в противном случае он также скопирует исходный каталог, а не его содержимое и становится/var/www/dev/html/xxxx
, что, возможно, не то, что вы хотите. the
--exclude
путь относительные непосредственно к источнику. Даже если вы поставите полный абсолютный путь, это не сработает.-v
для подробного,-a
для режима архива, что означает, что вы хотите рекурсия и хотят сохранить почти все.