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不匹配*(它是一个点文件)。但是,有一些并发症:
如果您设置了该glob_dots选项,则还需要排除.svn:
svn mv !(2010|.svn) 2010 # requires setopt ksh_glob
svn mv *~(.svn|2010) 2010 # requires setopt extended_glob
Run Code Online (Sandbox Code Playgroud)如果您有 dot 文件但尚未设置glob_dots,则需要单独移动它们:
svn mv {^,}2010
svn mv .*~.svn 2010
Run Code Online (Sandbox Code Playgroud)
一次性完成:
svn mv *~(.svn|2010)(D) 2010
Run Code Online (Sandbox Code Playgroud)在这种情况下(如果您没有子目录)在 zsh 中工作的另一种方法是svn mv *(.D) 2010,仅匹配常规文件 ( .) 包括点文件 ( D)。