“Mkdir foo; svn mv * foo ”


9

Saya sering ingin melakukan beberapa varian dari ungkapan ini:

$ mkdir 2010
$ svn mv * 2010

Tentu saja, saya mendapatkan kesalahan karena glob juga cocok dengan 2010:

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

Apakah ada cara untuk mengganti "svn mv * 2010"dengan liner yang berbeda yang melakukan hal yang benar?


Ini bukan pertanyaan khusus untuk svn, ini berlaku untuk vanila mvjuga. Namun, dengan mv, mv * newdirbekerja untuk saya, meskipun dengan kesalahan.
crazy2be

Jawaban:


14

Di bawah ksh, bash, atau zsh:

svn mv !(2010) 2010

Di bawah bash, Anda harus menjalankannya shopt -s extglobdulu (letakkan di Anda ~/.bashrc). Di bawah zsh, Anda harus menjalankannya setopt -o ksh_globdulu (letakkan di Anda ~/.zshrc).

Ini tidak memindahkan file dot (file yang namanya dimulai dengan .). Jika Anda memiliki beberapa, pindahkan secara terpisah. Berhati-hatilah untuk mengecualikan .svndirektori jika Anda memilikinya. Dalam ksh atau zsh:

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

Dalam bash, ini lebih rumit karena Anda juga perlu mengecualikan .dan ...

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

Zsh juga memiliki sintaks yang berbeda dan lebih pendek, yang mengharuskan berjalan setopt -o extended_globterlebih dahulu (sekali lagi, masukkan ini ~/.zshrc):

svn mv {^,}2010

Ekspansi brace pertama ikut berperan, menghasilkan svn mv ^2010 2010. Kemudian pola ^2010(jalan pintas untuk "file yang cocok *tetapi tidak 2010") diperluas.

Jika Anda memiliki .svndirektori, Anda harus mengeluarkannya dari pemindahan. Ini ok secara default, karena .svntidak cocok dengan *(ini file dot). Namun, ada beberapa komplikasi:

  • Jika Anda telah mengatur glob_dotsopsi, Anda harus mengecualikan .svnjuga:

    svn mv !(2010|.svn) 2010             # requires setopt ksh_glob
    svn mv *~(.svn|2010) 2010            # requires setopt extended_glob
  • Jika Anda memiliki file dot dan belum Anda atur glob_dots, Anda harus memindahkannya secara terpisah:

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

    Untuk melakukannya dalam sekali jalan:

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

Cara lain yang akan bekerja di zsh dalam kasus ini (jika Anda tidak memiliki subdirektori) adalah svn mv *(.D) 2010, untuk mencocokkan hanya file biasa ( .) termasuk file dot ( D).


3

ZSH memiliki operator glob yang membantu mencocokkan semuanya kecuali nama yang diberikan ^,. Jadi ini akan berhasil (tapi khusus ZSH, dan Anda harus setopt extendedglobterlebih dahulu):

$ svn mv ^2010 2010

Saya sudah tahu tentang !()sintaks yang berfungsi zsh. Apa ^perbedaan antara sintaksis? Ini tidak berfungsi di shell saya, opsi apa yang harus saya atur untuk mengaktifkannya?
Caleb

@ Caleb Maaf, saya pikir itu diaktifkan secara default, tetapi tampaknya Anda perlu setopt extendedglob. Saya tidak tahu !(), sepertinya cara yang lebih mudah untuk melakukannya
Michael Mrozek

svn mv {^,}2010untuk menghindari mengetik nama direktori dua kali
Gilles 'SO- stop being evil'

0

Jika file Anda memiliki nama "jinak" (tanpa spasi, karakter yang tidak diinginkan atau \[?*):

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

2
File tidak dapat dipercaya memiliki nama "jinak". Selalu :) Solusi glob shell disajikan untuk bash dan zsh dengan rapi menghindari masalah ini.
Caleb
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.