“Mkdir foo; svn mv * foo "

9

A menudo quiero hacer alguna variante de este idioma:

$ mkdir 2010
$ svn mv * 2010

Por supuesto, recibo un error porque el globo también coincide con 2010:

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

¿Hay alguna forma de reemplazarlo "svn mv * 2010"con un trazador de líneas diferente que haga lo correcto?

Lorin Hochstein
fuente
Esta no es una pregunta específica de svn, se aplica también a la vainilla mv. Sin embargo, con mv, mv * newdirfunciona para mí, aunque con un error.
crazy2be

Respuestas:

14

Bajo ksh, bash o zsh:

svn mv !(2010) 2010

En bash, debes ejecutar shopt -s extglobprimero (ponlo en tu ~/.bashrc). En zsh, debe ejecutar setopt -o ksh_globprimero (ponerlo en su ~/.zshrc).

Esto no mueve archivos de puntos (archivos cuyo nombre comienza con .). Si tiene algunos, muévalos por separado. Tenga cuidado de excluir el .svndirectorio si tiene uno. En ksh o zsh:

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

En bash, esto es más complicado porque también debes excluir explícitamente .y ...

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

Zsh también tiene una sintaxis diferente y más corta, que requiere ejecutarse setopt -o extended_globprimero (nuevamente, ponga esto ~/.zshrc)

svn mv {^,}2010

La primera expansión de llaves entra en juego, lo que resulta en svn mv ^2010 2010. Luego se expande el patrón ^2010(un acceso directo para "archivos que coinciden *pero no 2010").

Si tiene un .svndirectorio, deberá excluirlo del movimiento. Esto está bien por defecto, ya .svnque no coincide *(es un archivo de puntos). Sin embargo, hay complicaciones:

  • Si ha configurado la glob_dotsopción, deberá excluir .svntambién:

    svn mv !(2010|.svn) 2010             # requires setopt ksh_glob
    svn mv *~(.svn|2010) 2010            # requires setopt extended_glob
    
  • Si tiene archivos de puntos y no los ha configurado glob_dots, deberá moverlos por separado:

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

    Para hacerlo de una vez:

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

Otra forma que funcionaría en zsh en este caso (si no tiene subdirectorios) es svn mv *(.D) 2010hacer coincidir solo los archivos normales ( .), incluidos los archivos de puntos ( D).

Gilles 'SO- deja de ser malvado'
fuente
3

ZSH tiene un operador de pegote útiles para que coincida con todo, excepto un nombre dado, ^. Entonces esto funcionaría (pero es específico de ZSH, y setopt extendedglobprimero debe hacerlo ):

$ svn mv ^2010 2010
Michael Mrozek
fuente
Conozco la !()sintaxis con la que funciona zsh. ¿Cómo ^difiere la sintaxis? No funciona en mi shell, ¿qué opción necesitaría configurar para habilitarlo?
Caleb
@Caleb Lo siento, pensé que estaba activado por defecto, pero aparentemente lo necesitas setopt extendedglob. No lo sabía !(), suena como una forma más cruzada de hacerlo
Michael Mrozek
svn mv {^,}2010para evitar escribir el nombre del directorio dos veces
Gilles 'SO- deja de ser malvado'
0

Si sus archivos tienen nombres "domesticados" (sin espacios en blanco, caracteres no imprimibles o \[?*):

svn mv $(ls | grep -vx 2010) 2010
Chris Ting
fuente
2
No se puede confiar en que los archivos tengan nombres "domesticados". Ever :) Las soluciones de shell glob presentadas para bash y zsh evitan este problema.
Caleb