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 --exclude
plusieurs fois.
rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude --exclude anotherfoldertoexclude
Notez que l' option dir thefoldertoexclude
après --exclude
est relative à sourcefolder
, c'est-à-dire sourcefolder/thefoldertoexclude
.
Vous pouvez également ajouter -n
pour un essai à sec pour voir ce qui sera copié avant d'effectuer une opération réelle, et si tout va bien, supprimez -n
de la ligne de commande.
--exclude
thefoldertoexclude
relatif au sourcefolder
ou 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_GLOB
et 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~y
modè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
zsh
quand même.
setopt -u extglob
.
Pourquoi utiliser rsync
quand 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.
-path
argument 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
, cp
est 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/.git
d'ê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
ls
et simplement le faire cp !(file1|file1) dest
.
cp $(ls folder/!exclude_folder0|exclude_folder1)) dest
rsync
est en fait assez délicat. avoir à faire plusieurs tests pour le faire fonctionner.
Supposons que vous souhaitiez copier /var/www/html
dans, /var/www/dev
mais 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 --exclude
chemin est relatif à la source directement. Même si vous mettez le chemin absolu complet, cela ne fonctionnera pas.
-v
est pour verbeux, -a
est 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
cp
un 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 ls
tous les fichiers mais les fichiers spécifiques cachés avec indicateur -I
. La sortie de ls
est utilisée comme entrée standard pour la deuxième partie. xargs
construire et exécuter la commande à cp -rf -t destdir
partir de l'entrée standard. l'indicateur -r
signifie copier les répertoires de manière récursive, -f
signifie copier les fichiers de force qui écraseront les fichiers dans le destdir
, -t
spécifiez la copie du répertoire de destination vers.
cp -r ls -A | grep -v "Excluded_File_or_folder"
../$target_location -v