"mkdir foo; svn mv * foo"

Lor*_*ein 9 shell directory wildcards rename

我经常想做这个习语的一些变体:

$ mkdir 2010
$ svn mv * 2010
Run Code Online (Sandbox Code Playgroud)

当然,我得到一个错误,因为 glob 也匹配 2010:

svn: Cannot copy path '2010' into its own child '2010/2010'
Run Code Online (Sandbox Code Playgroud)

有没有办法"svn mv * 2010"用不同的单线替换做正确的事情?

Gil*_*il' 14

在 ksh、bash 或 zsh 下:

svn mv !(2010) 2010
Run Code Online (Sandbox Code Playgroud)

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

这不会移动点文件(名称以 开头的文件.)。如果您有一些,请单独移动它们。.svn如果您有目录,请注意排除该目录。在 ksh 或 zsh 中:

svn mv !(2010) .!(svn) 2010
Run Code Online (Sandbox Code Playgroud)

在 bash 中,这更复杂,因为您还需要明确排除...

svn mv !(2010) .!(svn|.|) 2010
Run Code Online (Sandbox Code Playgroud)

Zsh 也有一个不同的、更短的语法,它需要setopt -o extended_glob先运行(同样,把它放在 中~/.zshrc):

svn mv {^,}2010
Run Code Online (Sandbox Code Playgroud)

第一个大括号扩展开始发挥作用,导致svn mv ^2010 2010. 然后模式^2010(“文件匹配*但不匹配”的快捷方式2010)被扩展。

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

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