«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?

Lorin Hochstein
la source
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).

Gilles 'SO- arrête d'être méchant'
la source
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
Michael Mrozek
la source
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
Chris Ting
la source
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