I often want to do some variant of this idiom:
$ mkdir 2010 $ svn mv * 2010
Of course, I get an error because the glob matches 2010 as well:
svn: Cannot copy path '2010' into its own child '2010/2010'
Is there a way to replace "svn mv * 2010" with a different one-liner that does the right thing?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Under ksh, bash or zsh:
svn mv !(2010) 2010
Under bash, you need to run shopt -s extglob first (put it in your ~/.bashrc). Under zsh, you need to run setopt -o ksh_glob first (put it in your ~/.zshrc).
This doesn’t move dot files (files whose name begins with .). If you have some, move them separately. Take care to exclude the .svn directory if you have one. In ksh or zsh:
svn mv !(2010) .!(svn) 2010
In bash, this is more complicated because you also need to explicitly exclude . and ...
svn mv !(2010) .!(svn|.|) 2010
Zsh also has a different, shorter syntax, which requires running setopt -o extended_glob first (again, put this in ~/.zshrc):
svn mv {^,}2010
First brace expansion comes into play, resulting in svn mv ^2010 2010. Then the pattern ^2010 (a shortcut for “files matching * but not 2010”) is expanded.
If you have a .svn directory, you’ll need to exclude it from the move. This is ok by default, as .svn is not matched by * (it’s a dot file). However, there are complications:
-
If you’ve set the
glob_dotsoption, you’ll need to exclude.svnas well:svn mv !(2010|.svn) 2010 # requires setopt ksh_glob svn mv *~(.svn|2010) 2010 # requires setopt extended_glob
-
If you have dot files and you haven’t set
glob_dots, you’ll need to move them separately:svn mv {^,}2010 svn mv .*~.svn 2010To do it in one go:
svn mv *~(.svn|2010)(D) 2010
Another way that would work in zsh in this case (if you have no subdirectories) is svn mv *(.D) 2010, to match only regular files (.) including dot files (D).
Method 2
ZSH has a helpful glob operator to match everything except a given name, ^. So this would work (but it’s ZSH specific, and you need to setopt extendedglob first):
$ svn mv ^2010 2010
Method 3
If your files have “tame” names (no whitespace, unprintable characters or [?*):
svn mv $(ls | grep -vx 2010) 2010
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0