Je souhaite copier tous les fichiers d'un répertoire, à l'exception de certains fichiers d'un sous-répertoire spécifique. J'ai remarqué que la commande 'cp' n'avait pas d'option --exclude. Alors, comment puis-je y parvenir?
tar -c | tar -x?
Je souhaite copier tous les fichiers d'un répertoire, à l'exception de certains fichiers d'un sous-répertoire spécifique. J'ai remarqué que la commande 'cp' n'avait pas d'option --exclude. Alors, comment puis-je y parvenir?
tar -c | tar -x?
Réponses:
rsync est rapide et facile:
rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude
Vous pouvez utiliser --excludeplusieurs fois.
rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude --exclude anotherfoldertoexclude
Notez que l' option dir thefoldertoexcludeaprès --excludeest relative à sourcefolder, c'est-à-dire sourcefolder/thefoldertoexclude.
Vous pouvez également ajouter -npour un essai à sec pour voir ce qui sera copié avant d'effectuer une opération réelle, et si tout va bien, supprimez -nde la ligne de commande.
--exclude
thefoldertoexcluderelatif au sourcefolderou le répertoire de travail actuel? merci
rsync -av --progress --exclude="thefoldertoexclude" sourcefolder /destinationfolder- de toute façon un vote positif pour le rsync au lieu de la recherche, car vous pouvez facilement utiliser des chemins absolus pour la source tandis que dans la recherche, c'est plus difficile car il utilise le {}dans le dst.
$ rsync user@example.com:/var/www/mypage /var/www/mylocalpage/ou du local à distant$ rsync /var/www/mylocalpage/ user@example.com:/var/www/mypage
Eh bien, si l'exclusion de certains modèles de nom de fichier devait être effectuée par chaque utilitaire de fichier unix-ish (comme cp, mv, rm, tar, rsync, scp, ...), une immense duplication des efforts se produirait. Au lieu de cela, ces choses peuvent être effectuées dans le cadre de la globalisation , c'est-à-dire par votre shell.
man 1 bash, / extglob .
Exemple:
$ 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
Donc, vous venez de mettre un motif à l'intérieur !(), et cela annule la correspondance. Le modèle peut être arbitrairement complexe, à partir de l'énumération des chemins individuels (comme Vanwaril le montre dans une autre réponse):, !(filename1|path2|etc3)à des choses semblables à des regex avec des étoiles et des classes de caractères. Reportez-vous à la page de manuel pour plus de détails.
man 1 zshexpn, / génération de nom de fichier .
Vous pouvez faire setopt KSH_GLOBet utiliser des modèles de type bash. Ou,
% setopt EXTENDED_GLOB % images d'écho / * images / 004.bmp images / 033.jpg images / 1276338351183.jpg images / 2252.png % écho images / * ~ * .jpg images / 004.bmp images / 2252.png
Correspond donc au x~ymodèle x, mais exclut le modèle y. Encore une fois, pour plus de détails, reportez-vous à la page de manuel.
La coquille de poisson a une réponse beaucoup plus jolie à cela:
🐟 cp (string match -v '* .excluded.names' - srcdir / *) destdir
Tapez cp *, appuyez CtrlX*et voyez ce qui se passe. ce n'est pas nocif je le promets
zshquand même.
setopt -u extglob.
Pourquoi utiliser rsyncquand vous pouvez le faire:
find . -type f -not -iname '*/not-from-here/*' -exec cp '{}' '/dest/{}' ';'
Cela suppose que la structure du répertoire cible est la même que celle de la source.
-pathargument pour tester les hiérarchies de chemins, pas
find . -type f -not -path '*/not-from-here/*' -exec cp '{}' '/dest/{}' \;
rsync? Parce qu'il peut ne pas être présent dans le système! tandis que find, cpest toujours à leur place. Ou vous, du genre de gars, qui avez installé 2 concerts pour faire des choses simples?
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 }
Le moyen le plus simple que j'ai trouvé, où vous pouvez copier tous les fichiers à l'exception des fichiers et des dossiers simplement en ajoutant leurs noms entre parenthèses:
shopt -s extglob
cp -r !(Filename1 | FoldernameX | Filename2) Dest/
-bash: !: event not found
Développer le commentaire de mvds , cela fonctionne pour moi
cd dotfiles
tar -c --exclude .git --exclude README . | tar -x -C ~/dotfiles2
C'est relatif au répertoire source.
Cela exclura le répertoire source/.gitd'être copié.
rsync -r --exclude '.git' source target
rsync
rsync -r --verbose --exclude 'exclude_pattern' ./* /to/where/
et essayez d'abord avec l'option -n pour voir ce qui va être copié
Je suppose que vous utilisez bash ou dash. Est-ce que cela fonctionnerait?
shopt -s extglob # sets extended pattern matching options in the bash shell
cp $(ls -laR !(subdir/file1|file2|subdir2/file3)) destination
Faire un ls en excluant les fichiers dont vous ne voulez pas, et l'utiliser comme premier argument pour cp
lset simplement le faire cp !(file1|file1) dest.
cp $(ls folder/!exclude_folder0|exclude_folder1)) dest
rsyncest en fait assez délicat. avoir à faire plusieurs tests pour le faire fonctionner.
Supposons que vous souhaitiez copier /var/www/htmldans, /var/www/devmais que vous deviez exclure le /var/www/html/site/video/ répertoire, peut-être en raison de sa taille. La commande serait:
rsync -av --exclude 'sites/video' /var/www/html/ /var/www/dev
Quelques mises en garde :
/dans la source est nécessaire, sinon elle copiera également le répertoire source plutôt que son contenu et deviendra /var/www/dev/html/xxxx, ce qui n'est peut-être pas ce que vous voulez.Le --excludechemin est relatif à la source directement. Même si vous mettez le chemin absolu complet, cela ne fonctionnera pas.
-vest pour verbeux, -aest pour le mode archive, ce qui signifie que vous voulez la récursivité et que vous souhaitez conserver presque tout.
cp -rv `ls -A | grep -vE "dirToExclude|targetDir"` targetDir
Edit: oublié d'exclure également le chemin cible (sinon il serait récursivement copié).
Il s'agit d'une modification de la réponse de Linus Kleen. Sa réponse n'a pas fonctionné pour moi car il y en aurait un. ajouté devant le chemin du fichier que cp n'aime pas (le chemin ressemblerait à source / .destination / file).
Cette commande a fonctionné pour moi:
find . -type f -not -path '*/exlude-path/*' -exec cp --parents '{}' '/destination/' \;
la commande --parents conserve la structure du répertoire.
mv tobecopied/tobeexcluded .
cp -r tobecopied dest/
mv tobeexcluded tobecopied/
Déplacez-le simplement temporairement dans un répertoire caché (et renommez-le après, si vous le souhaitez).
mkdir .hiddendir
cp * .hiddendir -R
mv .hiddendir realdirname
cpun shell POSIX standard comme sh.
J'utilise une boucle "do while" pour lire la sortie de la commande find. Dans cet exemple, je fais correspondre (plutôt que d'exclure) certains modèles car il y a un nombre plus limité de correspondances de modèles que je veux que je ne veux pas. Vous pouvez inverser la logique avec un -not devant les drapeaux -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
J'utilise ce qui précède pour copier tous les fichiers de type de musique qui sont plus récents sur mon serveur que les fichiers sur un Western Digital TV Live Hub que j'ai monté dans / media / wd. J'utilise ce qui précède parce que j'ai beaucoup de fichiers DVD, mpeg, etc. que je veux exclure ET parce que pour une raison quelconque, rsync semble copier, mais après avoir regardé le périphérique wd, les fichiers ne sont pas là malgré aucun erreurs lors de la rsync avec cette commande:
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
La première partie lstous les fichiers mais les fichiers spécifiques cachés avec indicateur -I. La sortie de lsest utilisée comme entrée standard pour la deuxième partie. xargsconstruire et exécuter la commande à cp -rf -t destdirpartir de l'entrée standard. l'indicateur -rsignifie copier les répertoires de manière récursive, -fsignifie copier les fichiers de force qui écraseront les fichiers dans le destdir, -tspécifiez la copie du répertoire de destination vers.
cp -r ls -A | grep -v "Excluded_File_or_folder"../$target_location -v