«Mkdir foo; svn mv * foo ”


9

Je veux souvent faire une variante de cet idiome:

$ mkdir 2010
$ svn mv * 2010

Bien sûr, je reçois une erreur car le glob correspond également à 2010:

svn: Cannot copy path '2010' into its own child '2010/2010'

Y a-t-il un moyen de le remplacer "svn mv * 2010"par un autre doublure qui fait la bonne chose?


Ce n'est pas une question spécifique à svn, elle s'applique également à la vanille mv. Cependant, avec mv, mv * newdirfonctionne pour moi, mais avec une erreur.
crazy2be

Réponses:


14

Sous ksh, bash ou zsh:

svn mv !(2010) 2010

Sous bash, vous devez d' shopt -s extglobabord exécuter (mettez-le dans votre ~/.bashrc). Sous zsh, vous devez d' setopt -o ksh_globabord exécuter (mettez-le dans votre ~/.zshrc).

Cela ne déplace pas les fichiers de points (fichiers dont le nom commence par .). Si vous en avez, déplacez-les séparément. Veillez à exclure le .svnrépertoire si vous en avez un. En ksh ou zsh:

svn mv !(2010) .!(svn) 2010

En bash, c'est plus compliqué car vous devez également exclure explicitement .et ...

svn mv !(2010) .!(svn|.|) 2010

Zsh a également une syntaxe différente et plus courte, qui nécessite d'être exécutée en setopt -o extended_globpremier (encore une fois, mettez-la ~/.zshrc):

svn mv {^,}2010

La première extension de l'entretoise entre en jeu, résultant en svn mv ^2010 2010. Ensuite, le modèle ^2010(un raccourci pour «les fichiers correspondent *mais pas 2010») est développé.

Si vous avez un .svnrépertoire, vous devrez l'exclure du déplacement. C'est ok par défaut, car il .svnne correspond pas à *(c'est un fichier de points). Cependant, il y a des complications:

  • Si vous avez défini l' glob_dotsoption, vous devrez également exclure .svn:

    svn mv !(2010|.svn) 2010             # requires setopt ksh_glob
    svn mv *~(.svn|2010) 2010            # requires setopt extended_glob
  • Si vous avez des fichiers de points et que vous ne les avez pas définis glob_dots, vous devrez les déplacer séparément:

    svn mv {^,}2010
    svn mv .*~.svn 2010

    Pour le faire en une seule fois:

    svn mv *~(.svn|2010)(D) 2010

Une autre façon qui fonctionnerait dans zsh dans ce cas (si vous n'avez pas de sous-répertoires) est de svn mv *(.D) 2010faire correspondre uniquement les fichiers réguliers ( .), y compris les fichiers de points ( D).


3

ZSH a un opérateur utile glob de tout sauf un nom correspond donné ^. Donc cela fonctionnerait (mais c'est spécifique à ZSH, et vous devez d' setopt extendedglobabord):

$ svn mv ^2010 2010

Je connais la !()syntaxe qui fonctionne avec zsh. En quoi la ^syntaxe diffère-t-elle? Cela ne fonctionne pas dans mon shell, quelle option devrais-je définir pour l'activer?
Caleb

@Caleb Désolé, je pensais que c'était activé par défaut, mais apparemment vous en avez besoin setopt extendedglob. Je ne savais pas !(), ça ressemble à une façon plus cross-shell de le faire
Michael Mrozek

svn mv {^,}2010pour éviter de taper deux fois le nom du répertoire
Gilles 'SO- arrête d'être méchant'

0

Si vos fichiers ont des noms «apprivoisés» (pas d'espaces, de caractères non imprimables ou \[?*):

svn mv $(ls | grep -vx 2010) 2010

2
Les fichiers ne peuvent pas être approuvés pour avoir des noms "apprivoisés". Jamais :) Les solutions shell glob présentées pour bash et zsh contournent proprement ce problème.
Caleb
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.