Liste d'exclusion mv en ligne de commande

11

Existe-t-il un moyen de mv, cpou une opération de fichier telle que je puisse spécifier tous les fichiers que je ne veux pas affecter?

Par exemple, dire que j'ai un dossier avec les fichiers file1, file2et file3, et je veux aller file1et file2quelque part. Plutôt que de nommer explicitement les fichiers à déplacer ( mv file1 file2 /path/to/destination), je veux nommer les fichiers à ne pas déplacer et que tous les autres du dossier soient déplacés ( mv --some-switch file3 /path/to/destination)

Glide
la source
Je crois que mv file1 file2 /path/to/destinationcela ne fera pas ce que vous voulez qu'il fasse
phunehehe

Réponses:

19
  • Vous pouvez utiliser les modèles de globalisation avancés dans certains shells pour faire correspondre tous les fichiers d'un répertoire, à l'exception de ceux correspondant à un modèle particulier. Par exemple, dans ksh, bash ou zsh, la commande

    shopt -s extglob   ## needed in bash only
    setopt ksh_glob   ## needed in zsh only
    mv /source/!(*.bak) /destination
    

    déplacera tous les fichiers dans /sourceà l' /destinationexception des fichiers correspondants *.bak. Dans zsh, vous pouvez également écrire /source/^*.baksi vous exécutez pour la première fois setopt extended_glob, et plus généralement (nécessitant à nouveau setopt extended_glob) /source/*~*.bak(ou /source/a*~*.bakpour tous les fichiers dont le nom commence par à l' aexception des .bakfichiers, etc.).

  • Zsh possède une commande de copie / déplacement / liaison de masse qui peut être utilisée, entre autres, pour déplacer tous les fichiers à l'exception de ceux correspondant à un modèle. Par exemple, la commande suivante déplace tous les fichiers sauf *.bakde /sourcevers targetet ajoute .bakà leur nom dans le processus:

    autoload zmv
    zmv '/source/(*)~*.bak' '/target/$1.bak'
    
  • Il existe plusieurs commandes appelées renameflottantes. Sur Debian et Ubuntu, /usr/bin/renameest un script perl qui déplace les fichiers vers un nouveau nom généré par une expression perl. Vous pouvez exclure des fichiers de renommer en ne générant pas un nouveau nom si le fichier doit être exclu. Par exemple, la commande suivante (à l'aide de ce renameprogramme particulier ) déplace tous les fichiers sauf *.bakde /sourcevers /target:

    rename 's!/source!/target! unless m!\.bak$!' /source/*
    
  • Vous pouvez utiliser la findcommande pour sélectionner les fichiers que vous souhaitez déplacer. Par exemple, la commande suivante déplace tous les fichiers normaux sauf *.bakdans /sourceou un sous-répertoire vers /target(notez que la structure du répertoire est réduite):

    find /source -type f \! -name '*.bak' -exec mv {} /target/ \;
    

    ou (plus efficace s'il y a beaucoup de fichiers à déplacer)

    find /source -type f \! -name '*.bak' -exec sh -c 'mv "$@" "$0"' /target/ {} +
    
  • rsyncest une généralisation de cpet scpavec comprennent très puissant / règles d' exclusion. Par exemple, la commande suivante copie tous les fichiers sauf *.bakdans /sourceou un sous-répertoire dans /target, en respectant la structure du répertoire:

    rsync -a --exclude '*.bak' /source/ /target/
    
  • paxest (entre autres) un autre cpsur les stéroïdes. Ses règles d'exclusion ne sont pas aussi puissantes que celles de rsync, mais il a la possibilité supplémentaire de renommer les fichiers lorsqu'ils sont copiés. Si vous renommez un fichier en chaîne vide, il est exclu de la copie. Par exemple, la commande suivante copie tous les fichiers sauf *.bakdans /sourceou un sous-répertoire dans /targetet renomme les fichiers .baken passant.

    cd /source && pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' . /target/
    

    L'exemple ci-dessus a l'effet secondaire malheureux de créer des répertoires appelés foo.bak, qui peuvent être évités en combinant findavec pax:

    { cd /source && find . -type f; } | \
    pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' /target/
    
Gilles 'SO- arrête d'être méchant'
la source
Impressionnant. Une correction possible: je pense que la findcommande doit se terminer\;
Steven D
@Steven: Merci, je ne cesse d'oublier que vous ne pouvez utiliser que +immédiatement après {}.
Gilles 'SO- arrête d'être méchant'
belle liste, merci pour ça. :-)
echox
1
quelle réponse,
bravo