“ mkdir foo; svn mv * foo”


9

我经常想对这个习语做一些变形:

$ mkdir 2010
$ svn mv * 2010

当然,我会收到一个错误,因为该组也匹配2010:

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

有没有办法替换"svn mv * 2010"做正确的事情的另一种单缸纸?


这不是SVN特有的问题,它也适用于香草mv。但是,使用mvmv * newdir虽然有错误,但对我有用。
crazy2be

Answers:


14

在ksh,bash或zsh下:

svn mv !(2010) 2010

在bash下,您需要先运行shopt -s extglob(将其放入~/.bashrc)。在zsh下,您需要先运行setopt -o ksh_glob(将其放入~/.zshrc)。

这不会移动点文件(名称以开头的文件.)。如果有,请分别移动它们。.svn如果有目录,请小心排除目录。在ksh或zsh中:

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

在bash中,这更加复杂,因为您还需要显式排除...

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

Zsh还具有不同的较短语法,它需要setopt -o extended_glob首先运行(再次将其放入~/.zshrc):

svn mv {^,}2010

首先进行括号扩展,结果为svn mv ^2010 2010。然后扩展模式^2010(“文件匹配*但不是2010” 的快捷方式)。

如果您有.svn目录,则需要将其从移动中排除。默认情况下是可以的,因为.svn没有匹配*(这是一个点文件)。但是,有一些并发症:

  • 如果设置了该glob_dots选项,则还需要排除.svn

    svn mv !(2010|.svn) 2010             # requires setopt ksh_glob
    svn mv *~(.svn|2010) 2010            # requires setopt extended_glob
    
  • 如果您有点文件并且尚未设置glob_dots,则需要分别移动它们:

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

    一口气做到:

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

在这种情况下(如果您没有子目录)svn mv *(.D) 2010,在zsh中可用的另一种方法是,仅匹配常规文件(.)包括点文件(D)。


3

ZSH有一个有用的全局运算符,用于匹配除给定名称之外的所有内容^。所以这可以工作(但是它是ZSH特有的,您需要setopt extendedglob首先这样做):

$ svn mv ^2010 2010

我知道!()与配合使用的语法zsh。如何在^语法有什么不同?它在我的shell中不起作用,我需要设置哪个选项来启用它?
卡莱布

@Caleb对不起,我认为默认情况下处于启用状态,但是显然您需要这样做setopt extendedglob。我不知道!(),这听起来像是一种跨领域的做法
Michael Mrozek

svn mv {^,}2010避免两次输入目录名称
Gilles'SO-别再作恶了'

0

如果您的文件具有“ tame”名称(没有空格,不可打印的字符或\[?*):

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

2
无法相信文件具有“ tame”名称。Ever :)针对bash和zsh提出的shell glob解决方案巧妙地避开了这个问题。
卡莱布
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.