docker $PWD路径_终端效率提升:自动路径切换

终端下工作最烦躁的就是路径切换,没有自动路径切换的帮助,就像在泥里走路;用熟练了 z / autojump / fasd 之类的工具,就像终端里溜冰,路劲切换从此指哪打哪。

拒绝用它们的原因,首先是没搞懂原理,不清楚它会跳到哪,想自己控制,怕它跳到不希望的地方又要跳回来麻烦。还有一些人实际用了一下,因为不熟练,感觉还没有 cd 那么快,其实任何东西都有一个熟悉过程,你用自己熟练了若干年的 cd 命令来比较刚用了两分钟的 z 命令,就像才开始学自行车,左歪一下右歪一下,你觉得没你走路快遂放弃学车,这不是很荒谬么?

学吉他都要手疼几个星期呢,想提升效率,没点代价行么?所以想用的好用的顺畅,首先花十多分钟研究一下他们的原理,再花十多分钟实际练习下,不超过半小时,能让你在终端下的工作效率提升一倍以上,这个投资值不值得呢?

autojump / z 到底选哪个 ?

当然选 z ,autojump 是最早的自动路径切换工具,好像是一个台湾小伙开发的,自动路径切换这个概念最早就是它提出来的,z 作为它的继承者,有几方面优势:

轻量级:autojump 有十多个源文件,四千行代码;z 只有 z.sh 一个源文件,两百行代码。

性能好:z 的性能是 autojump 的两倍以上。

无依赖:autojump 使用 py 开发,可能要另安装,z 只需要所有系统都自带的 bash/awk。

更精准:z 的匹配算法使用类似 FireFox 的 frecent 算法,充分考虑访问时间和次数。

z 做的事情和 autojump 做的差不多,但更加高效精准,更加轻量级,只有一个文件,可以附带在你的配置文件仓库里,和你的其他配置文件一起部署。

autojump 不但慢,而且十分笨重,俨然是一个小项目了,只有用包管理安装,或者克隆下来 make install。光冲这部署方式,就足够你抛弃 autojump 切换到 z 了。

两百多行 shell 在 github 拥有 8925 颗星,比前辈 autojump 还高,足见其受欢迎程度。

怎么安装呢?

建议直接把 z.sh 放到你 github 的 config 仓库里,随同部署,然后 bashrc 加一行:

source /path/to/z.sh

你就可以在 bash 中用 “z”命令使用它了。别忘了它的下载地址是:

https://github.com/rupa/z

我在本专栏前面的文章《提高效率从编写 init.sh 开始》里反复强调,把配置用 github 管理起来,有恒产才会有恒心,没有积累怎么可能提升效率?

工作原理:路径收集

Bash 里有一个 $PROMPT_COMMAND 环境变量,在你每按一次回车,显示命令提示符 "$" 的时候,就会去执行里面的命令。z.sh 定义了一个叫做 _z 的 shell 函数,并把命令:

_z --add "$(pwd)"

添加到 $PROMPT_COMMAND 末尾,这样每次显示命令提示符的时候就会被调用。zsh 中也有类似的机制,z.sh 依靠该命令不停的收集你当前的路径,在你每敲完一条 shell 命令之后,z.sh 都会获取最新的当前路径,保存到 $HOME/.z 数据文件中。

数据文件 $HOME/.z 的内容为:

/home/skywind/github/docker/apache2|48|1542554142
/home/skywind/docker/gogs/data|6|1542143205
/etc/apt/sources.list.d|12|1541778322
/home/skywind/github/docker/debian/debian-jessie|2|1542461714
/home/skywind/github/docker/mysql/8.0|169|1542536861
/home/skywind/docker/apache2|81|1542537066
/home/skywind/github/docker/debian/stretch-init/build/bin|4|1542517607
/home/skywind/docker/gogs|31|1542143626 

每一行代表一条记录,格式为:path | rank | time

路径名用于跳转时候的字符串匹配,访问次数(rank)和时间戳用于多个结果里的权重比较。所谓路径收集,就是跟踪你去到过的所有地方,并且更新上面的数据文件,加入新数据,或者增加老路径的访问次数。

随着数据越来越多,z.sh 一旦发现所有路径的 rank 加起来超过 9000 的话,就进行 aging 操作,将数据库里的 rank 统一乘以 0.99,然后删除结果小于 1 的路径。这样就会剔除一些很不常去的路径,保留你最经常去的地方,如此,数据文件能够控制在合理的大小。

每次更新路径时,z.sh 还会剔除一些被删除的,不存在的无效路径,该操作很快 10000 次检测的时间不会超过 10 豪秒。z.sh 依靠上述规则,完成数据库文件的维护。

匹配算法:Frecent

跳转命令可以提供一个或者多个关键字:

z key1 [key2 key3  ...]

当我们使用上述命令进行路径切换时,z.sh 首先会筛选出数据库里路径名匹配上述关键字的记录来,匹配采用顺序匹配,规则是:第一个关键字从路径名字符串的开头匹配,后面的关键字从上一个关键字被匹配到的位置之后开始匹配。也就是说假设数据库里有:

/home/user/github/src
/home/user/src/github

两条记录,你光使用 "github" 关键字会同时匹配到两条数据,而使用 "github src" 来匹配的话,只会匹配到第一条,因为先要匹配到 github,再从匹配位置往后匹配 src,所以第二条路径就不满足规则。关键字可以使用正则,比如使用单个关键字 "src$" 也可以只匹配第一条。

所以你数据库里类似的路径名很多的话,你可以多提供一两个关键字,就能增加匹配效率。完成路径名匹配后,z.sh 会筛选出一批候选路径,然后根据所有路径的 rank 和 time 计算一个分数 frecent:

function frecent(rank, time) {
	# relate frequency and time
	dx = t - time
	if( dx < 3600 ) return rank * 4
	if( dx < 86400 ) return rank * 2
	if( dx < 604800 ) return rank / 2
	return rank / 4
}

z.sh 通过管道将上面函数传递给 awk 进行计算,使用当前时间和时间戳的差值计算:

  • 一小时内访问过:frecent = rank * 4
  • 一天内访问过:frecent = rank * 2
  • 一周内访问过:frecent = rank / 2
  • 超过一周:frecent = rank / 4

这个 frecent 的计算方法是 FireFox 匹配历史 URL 用的,z.sh 将他移植了过来,同时兼顾了历史路径的访问次数和最近访问情况,认为访问次数越高的路径越重要,同时越是最近访问过的路径越重要,这比当纯使用一个权重的 autojump 更加科学和精准。

计算完后 z.sh 选择 frecent 最高的备选路径,作为跳转的目的地址。z.sh 两百多行的代码基本上就是在做路径收集和匹配这两件事情。

实际使用

光敲一个 "z" 命令,后面没有参数,查看历史进入过的路径:

24728af0b3ec73e7bef64b416fe7739d.png

便于演示,我裁剪了一下我的 .z 文件,左边是计算过的 frecent 分数,右边是路径名。随便使用 cd 命令跳转一下,再运行 z ,看看列表里新路径是否被加入?老路径权重是否有变化?接着用 z 后面加一个关键词就能跳到所有匹配的历史路径中权重最高的那个:

29af350a80470ed4c8ab5e5214047861.png

比如所有历史路径都包含 o ,那么 z o 就会跳转到权重最高的 ~/software 目录中。使用:“z -l foo" 可以列出包含 foo 的所有历史路径:

b6a33ea5aa1e6a9b32ce3081d6e5e26e.png

比如你不确定某个关键字会匹配到哪个路径,可以用 z -l 命令将满足名字匹配的路径通通列出来。比如上面列出了所有包含 c 字母的路径,这样看一眼避免挑错。有时候不少路径名十分相似,比如:

project1/src
project2/src

那么你 z src 的时候可能并不能如你愿跳转到你想要去的路径,那怎么办呢?

增加一个关键字即可,比如 z 1 src ,空格分隔多个关键字,z会先匹配出第一个来,比如1 ,然后再匹配第二个 src ,马上锁定 project1/src 了。这样虽然历史中多个路径都带有 src 关键字,但是你加入了其他关键字就可以精确的锁定你要去的地方。

另一种做法是实际 cd project1/src 过去,增加它的权重,权重超过 project2/src 那么下次 z src 的时候就会跳转过去,你可以实时用 z -l src 查看包含 src 的所有路径和权重。

经验技巧

实际使用起来,一般是 z + 最后一级目录名,比如:

$ z vim     # -> /home/skywind/software/vim
$ z tmp     # -> /home/skywind/tmp
$ z local   # -> /home/skywind/.local

99%的时候这样做就足够了,当没有按照你要求跳转的时候,你可以再补充一下再上一级目录的一些信息,比如 z vim/src 或者 z v src 就够了,弄不明白会跳转到哪里,可以随时用:

$ z -l key1 [key2 ... ]

查看权重。不过常使用你根本必担心这个问题,基本上常去的地方,z 都是指哪打哪。有时候如果处在一个顶层目录,确定要跳转到一个子目录,可以用 z -c 命令限制匹配当前目录的子目录,我们可以 alias 一下:

alias zc='z -c'

这样 zc abc 就能跳转到子目录中包含 abc 的路径了。当然你也可以把 z -l 给 alias 成 zl,用起来也很方便。刚开始使用 z.sh,可以刻意将一些 cd 命令用 z 代替,跳错了就用 z -l 观察下原因,觉得含糊了就去读一遍项目 README,等你摸透了习惯了,你会发现 z 越来越顺手。

后 记

我现在基本不用 autojump / fasd 之流,只用 z 一个命令进行自动路径切换,z.sh 比他们两个性能好多了。在性能好的机器上或许不明显,找台性能差的或者 cygwin/msys 这种 I/O 很慢的系统下面,autojump / fasd 几乎不能用,可以卡到每按一次回车他们两个都要卡一秒,但是 z.sh 没这问题,在性能很差的电脑上你都基本感觉不到它的存在。

以前有个哥么,每次见他疯狂的敲 tab,我就知道他又卡在 cd 上了,每次补全都有好几个备选,敲了几个字母以为可以继续了,再按一次 tab,继续出来一堆候选让他接着输入,他一边狂敲 tab 一边嘴里骂个不停,敲一次骂一句。

自从我给他介绍了 z.sh,几天以后,他的脾气好了不少,邹着的眉头也舒展了,用之前他犹如一头不知道出路在哪的困兽;自从用上了 z.sh ,他成了一名来去无影的剑客,整个人的精神面貌得到了极大的改观,生活不再单调,工作充满欢笑!腰也不酸了,腿也不疼了,一口气完成六个需求!

--

PS:z.sh 的几个移植版本

我移植的 z.lua 支持 windows 和 posix shell (bash, zsh, ash, dash, busybox ...) :

  • skywind3000/z.lua

还有一个 powershell 的 port:

  • JannesMeyer/z.ps

恩,咱们对 Windows cmd/powershell 也同样不抛弃,不放弃!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值