我正在使用 rsync 备份脚本(请参见此处:https://codereview.stackexchange.com/questions/29429/push-backup-script)这会创建类似的目录
back-2015-07-02T21_18_01
现在假设我在命令行 ( zsh
) 上/path/to/my/backup/back-2015-07-02T21_18_01/home/myuser/myfiles/somedir/subdir/
并且我想切换到/path/to/my/backup/back-2016-04-02T21_17_01/home/myuser/myfiles/somedir/subdir/
.
最快/最好的方法是什么zsh
?我通常使用 zsh 菜单完成,因此如果我可以通过菜单选项卡完成选择另一个日期但保留当前子目录(仅来自其他备份日期),那就太好了。
答案1
将一个目录组件交换为另一个目录组件的一种方法zsh
是使用两个参数版本cd
:
cd old new
这会替换new
第一个子字符串匹配old
,并尝试将目录更改为结果路径。例如:
% pwd
/path/to/my/backup/back-2015-07-02T21_18_01/home/myuser/myfiles/somedir/subdir/
% cd "5-07-02T21_18_01" "6-04-02T21_17_01"
/path/to/my/backup/back-2016-04-02T21_17_01/home/myuser/myfiles/somedir/subdir/
% pwd
/path/to/my/backup/back-2016-04-02T21_17_01/home/myuser/myfiles/somedir/subdir/
搜索和替换完全在字符串级别完成,并且替换始终仅在第一个匹配项上完成。因此,如果您位于/foo/foo/foo/foo
,运行时cd foo bar
将始终尝试将目录更改为/bar/foo/foo/foo
,无论它是否实际存在。/foo/foo/bar/foo
即使它存在,它也不会去寻找像 的替代品。
第二个参数的补全由 提供compinit
,但您必须键入第一个参数(至少使用默认补全设置)。如果compinit
出于某种原因未启用,您可以通过运行autoload -U compinit; compinit
(并将其添加到您的~/.zshrc
)来更改它。
笔记:cd
支持和 new 字符串/
中的字符old
,这意味着您可以通过运行来切换/a/b/c/d
到。但在这种情况下,补全似乎不起作用,因此您也必须自己输入第二个参数。/x/y/z/c/d
cd a/b x/y/z
答案2
我喜欢务实,并且由于编写 zsh 补全超出了我当前的技能范围,因此我只是使用select
zsh (和 bash)的菜单系统编写一个特殊用途的函数。
cdd(){
typeset dir
typeset -a dirs
if [[ $PWD =~ ^(.*)(/back-[0-9-]+T[0-9_]+/)(.*)$ ]]
then for dir in "$match[1]"/*/"$match[3]"
do [ "$dir" != "$PWD" -a -d "$dir" ] && dirs+=("$dir")
done
select dir in "$dirs[@]"
do echo "$dir"
cd "$dir"
break
done
else echo "no date in $PWD"
fi
}
这会使用日期模式将当前目录分成围绕目录的三个部分,然后将其替换为 glob *
。结果列表由 zsh 提供,并带有1) ... 2) ...
样式菜单,您只需在其中输入 1 或 2 即可 cd 到该目录。