“Mkdir foo; svn mv * foo "


9

Spesso voglio fare una variante di questo linguaggio:

$ mkdir 2010
$ svn mv * 2010

Certo, ricevo un errore perché anche il glob corrisponde al 2010:

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

C'è un modo per sostituirlo "svn mv * 2010"con un diverso rivestimento che fa la cosa giusta?


Questa non è una domanda specifica per svn, si applica anche alla vaniglia mv. Tuttavia, con mv, mv * newdirfunziona per me, anche se con un errore.
crazy2be

Risposte:


14

Sotto ksh, bash o zsh:

svn mv !(2010) 2010

Sotto bash, devi shopt -s extglobprima correre (mettilo nel tuo ~/.bashrc). Sotto zsh, devi setopt -o ksh_globprima eseguirlo (mettilo nel tuo ~/.zshrc).

Questo non sposta i file di punti (file il cui nome inizia con .). Se ne hai alcuni, spostali separatamente. Fai attenzione a escludere la .svndirectory se ne hai una. In ksh o zsh:

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

In bash, questo è più complicato perché è necessario anche escludere esplicitamente .e ...

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

Zsh ha anche una sintassi diversa, più breve, che richiede l'esecuzione setopt -o extended_globprima (di nuovo, inseriscilo ~/.zshrc):

svn mv {^,}2010

Entra in gioco l'espansione della prima parentesi, risultante svn mv ^2010 2010. Quindi il modello ^2010(un collegamento per "corrispondenza dei file *ma non 2010") viene espanso.

Se hai una .svndirectory, dovrai escluderla dalla mossa. Questo è ok per impostazione predefinita, in quanto .svnnon corrisponde *(è un file punto). Tuttavia, ci sono complicazioni:

  • Se hai impostato l' glob_dotsopzione, dovrai anche escludere .svn:

    svn mv !(2010|.svn) 2010             # requires setopt ksh_glob
    svn mv *~(.svn|2010) 2010            # requires setopt extended_glob
  • Se hai file dot e non li hai impostati glob_dots, dovrai spostarli separatamente:

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

    Per farlo in una volta sola:

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

Un altro modo che funzionerebbe in zsh in questo caso (se non hai sottodirectory) è svn mv *(.D) 2010quello di abbinare solo i file regolari ( .) inclusi i file punto ( D).


3

ZSH ha un operatore glob utile per abbinare tutto tranne un determinato nome, ^. Quindi funzionerebbe (ma è specifico per ZSH e devi setopt extendedglobprima):

$ svn mv ^2010 2010

Conosco la !()sintassi che funziona zsh. In cosa ^differisce la sintassi? Non funziona nella mia shell, quale opzione dovrei impostare per abilitarlo?
Caleb,

@Caleb Siamo spiacenti, ho pensato che fosse attivo per impostazione predefinita, ma a quanto pare è necessario setopt extendedglob. Non lo sapevo !(), sembra un modo più cross-shell per farlo
Michael Mrozek

svn mv {^,}2010per evitare di digitare due volte il nome della directory
Gilles 'SO- smetti di essere malvagio' il

0

Se i tuoi file hanno nomi "addomesticati" (senza spazi bianchi, caratteri non stampabili o \[?*):

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

2
Non ci si può fidare che i file abbiano nomi "addomesticati". Mai :) Le soluzioni shell glob presentate per bash e zsh evitano chiaramente questo problema.
Caleb,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.