Я хочу скопировать все файлы в каталоге, кроме некоторых файлов в определенном подкаталоге. Я заметил, что команда 'cp' не имеет опции --exclude. Итак, как мне этого добиться?
tar -c | tar -x?
Я хочу скопировать все файлы в каталоге, кроме некоторых файлов в определенном подкаталоге. Я заметил, что команда 'cp' не имеет опции --exclude. Итак, как мне этого добиться?
tar -c | tar -x?
Ответы:
rsync быстр и прост:
rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude
Вы можете использовать --excludeкратные разы.
rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude --exclude anotherfoldertoexclude
Обратите внимание , что реж thefoldertoexcludeпосле --excludeопции относительно к sourcefolder, т sourcefolder/thefoldertoexclude.
Также вы можете добавить -nпробный запуск, чтобы увидеть, что будет скопировано перед выполнением реальной операции, и, если все в порядке, удалить -nиз командной строки.
--exclude
thefoldertoexcludeотносительный sourcefolderили текущий рабочий каталог? спасибо
rsync -av --progress --exclude="thefoldertoexclude" sourcefolder /destinationfolder- в любом случае upvote для rsync вместо find, поскольку вы можете легко использовать абсолютные пути для источника, а в find это сложнее, чем {}в dst.
$ rsync user@example.com:/var/www/mypage /var/www/mylocalpage/или с локального на удаленный$ rsync /var/www/mylocalpage/ user@example.com:/var/www/mypage
Что ж, если исключение определенных шаблонов имен файлов должно выполняться каждой файловой утилитой unix-ish (например, cp, mv, rm, tar, rsync, scp, ...), произойдет огромное дублирование усилий. Вместо этого, такие вещи могут быть сделаны как часть подстановка , то есть с помощью вашей оболочки.
man 1 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 1 zshexpn, / генерация имени файла .
Вы можете делать 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.
У раковины рыбы есть намного более симпатичный ответ на это:
🐟 cp (строка соответствует -v '* .excluded.names' - srcdir / *) destdir
Набери cp *, нажми CtrlX*и посмотри что получится. это не вредно, я обещаю
zshхотя.
setopt -u extglob.
Зачем использовать, rsyncкогда вы можете сделать:
find . -type f -not -iname '*/not-from-here/*' -exec cp '{}' '/dest/{}' ';'
Это предполагает, что структура целевого каталога совпадает с исходной структурой.
-pathаргумент для проверки иерархии путей, а не
find . -type f -not -path '*/not-from-here/*' -exec cp '{}' '/dest/{}' \;
rsync? Ведь это может отсутствовать в системе! в то время как find, cpвсегда на своих местах. Или вы из тех парней, которые установили 2 гига штуки, чтобы делать простые вещи?
cp -r `ls -A | grep -v "c"` $HOME/
# $1 = source path # $2 = destination path # $3 = filter copy_from_source_to_destination_except_filter() { cp -r $(ls -A $1 | grep -v -w $3 | awk -v path=$1 '{printf "%s/%s ", path, $1}') $2 }
Я нашел самый простой способ, где вы можете скопировать все файлы, кроме файлов и папок, просто добавив их имена в скобках:
shopt -s extglob
cp -r !(Filename1 | FoldernameX | Filename2) Dest/
-bash: !: event not found
Расширяя комментарий mvds , это работает для меня
cd dotfiles
tar -c --exclude .git --exclude README . | tar -x -C ~/dotfiles2
Это относительно исходного каталога.
Это исключит source/.gitкопирование каталога .
rsync -r --exclude '.git' source target
Rsync
rsync -r --verbose --exclude 'exclude_pattern' ./* /to/where/
и сначала попробуйте это с опцией -n, чтобы увидеть, что будет скопировано
Я предполагаю, что вы используете 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
lsи просто сделать cp !(file1|file1) dest.
cp $(ls folder/!exclude_folder0|exclude_folder1)) dest
rsyncна самом деле довольно сложно. нужно сделать несколько тестов, чтобы это работало.
Допустим, вы хотите скопировать /var/www/htmlв /var/www/devно необходимости исключить /var/www/html/site/video/ каталог , возможно , из - за его размера. Команда будет:
rsync -av --exclude 'sites/video' /var/www/html/ /var/www/dev
Некоторые оговорки :
/в источнике необходима, иначе она также будет копировать исходный каталог, а не его содержимое, и становится/var/www/dev/html/xxxx , что, возможно, не то, что вам нужно.--excludeПуть по отношению к источнику непосредственно. Даже если вы поставите полный абсолютный путь, он не будет работать.
-vдля подробного, -aдля режима архива, который означает, что вы хотите рекурсию и хотите сохранить почти все.
cp -rv `ls -A | grep -vE "dirToExclude|targetDir"` targetDir
Изменить: забыл исключить целевой путь, а также (в противном случае он будет копировать рекурсивно).
Это модификация ответа Линуса Клина. Его ответ не работает для меня, потому что будет. добавляется перед путем к файлу, который не нравится cp (путь будет выглядеть как source / .destination / file).
Эта команда работала для меня:
find . -type f -not -path '*/exlude-path/*' -exec cp --parents '{}' '/destination/' \;
Команда --parents сохраняет структуру каталогов.
Просто переместите его временно в скрытый каталог (и переименуйте его после, если хотите).
mkdir .hiddendir
cp * .hiddendir -R
mv .hiddendir realdirname
cpстандартной оболочкой POSIX sh.
Я использую цикл "do while", чтобы прочитать вывод команды find. В этом примере я сопоставляю (а не исключаю) определенные шаблоны, так как есть более ограниченное число сопоставлений с образцами, которые я хочу, чем те, которые я не хочу. Вы можете изменить логику с -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 $'\0' file; do cp -ruv "$file" "/media/wd/network_sync/music/$file"; done
Я использую вышеупомянутое, чтобы скопировать все файлы музыкального типа, которые являются более новыми на моем сервере, чем файлы на Live Digital Hub Western Digital TV, которые я смонтировал в / media / wd. Я использую вышеупомянутое, потому что у меня есть много файлов DVD, mpegs и т. Д., Которые я хочу исключить И, потому что по какой-то причине 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/
ls -I "filename1" -I "filename2" | xargs cp -rf -t destdir
Первая часть lsвсех файлов, но скрытые конкретные файлы с флагом -I. Вывод lsиспользуется как стандартный ввод для второй части. xargsпостроить и выполнить команду cp -rf -t destdirиз стандартного ввода. флаг -rозначает рекурсивное копирование каталогов, -fозначает принудительное копирование файлов, которые будут перезаписывать файлы в destdir, -tуказывать конечный каталог для копирования.
cp -r ls -A | grep -v "Excluded_File_or_folder"../$target_location -v