“mkdir foo; svn mv * foo ”

8

Muitas vezes, quero fazer alguma variante desse idioma:

$ mkdir 2010
$ svn mv * 2010

Claro, recebo um erro porque o glob corresponde a 2010 também:

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

Existe uma maneira de substituir "svn mv * 2010" por um one-liner diferente que faz a coisa certa?

    
por Lorin Hochstein 27.05.2011 / 22:07

3 respostas

13

Em ksh, bash ou zsh:

svn mv !(2010) 2010

No bash, você precisa executar shopt -s extglob primeiro (coloque em seu ~/.bashrc ). Sob zsh, você precisa executar setopt -o ksh_glob primeiro (coloque em seu ~/.zshrc ).

Isso não move os arquivos de ponto (arquivos cujo nome começa com . ). Se você tiver alguns, mova-os separadamente. Tome cuidado para excluir o diretório .svn se você tiver um. Em ksh ou zsh:

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

No bash, isso é mais complicado porque você também precisa excluir explicitamente . e .. .

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

O Zsh também tem uma sintaxe diferente, mais curta, que requer a execução de setopt -o extended_glob primeiro (novamente, coloque isso em ~/.zshrc ):

svn mv {^,}2010

A primeira expansão de chave entra em jogo, resultando em svn mv ^2010 2010 . Em seguida, o padrão ^2010 (um atalho para "arquivos correspondentes a * , mas não 2010 ") é expandido.

Se você tiver um diretório .svn , precisará excluí-lo do movimento. Isso é ok por padrão, já que .svn não é correspondido por * (é um arquivo de ponto). No entanto, existem complicações:

  • Se você definiu a opção glob_dots , também precisará excluir .svn :

    svn mv !(2010|.svn) 2010             # requires setopt ksh_glob
    svn mv *~(.svn|2010) 2010            # requires setopt extended_glob
    
  • Se você tiver arquivos de ponto e não tiver definido glob_dots , precisará movê-los separadamente:

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

    Para fazer de uma só vez:

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

Outra forma de trabalhar em zsh neste caso (se você não tiver subdiretórios) é svn mv *(.D) 2010 , para corresponder apenas aos arquivos regulares ( . ), incluindo os arquivos de ponto ( D ).

    
por 27.05.2011 / 23:59
3

O ZSH tem um operador glob útil para combinar tudo, exceto um nome, ^ . Então, isso funcionaria (mas é específico do ZSH, e você precisa setopt extendedglob primeiro):

$ svn mv ^2010 2010
    
por 27.05.2011 / 22:25
0

Se seus arquivos tiverem nomes "domesticados" (sem espaço em branco, caracteres não imprimíveis ou \[?* ):

svn mv $(ls | grep -vx 2010) 2010
    
por 27.05.2011 / 23:43