大多数 Bash 历史命令快捷键指南都会详尽列出所有可用的快捷键。问题在于,我可能只会使用一次某个快捷键,然后就会在尝试所有可能性时感到茫然。之后,我会继续日常工作,并完全忘记它们,只保留在我刚开始使用 Bash 时学到的众所周知的 !! 技巧。
因此,大多数快捷键从未被记住。
本文概述了我每天实际使用的快捷键。它基于我的书《Learn Bash the hard way》中的部分内容;(您可以阅读预览以了解更多信息)。
当人们看到我使用这些快捷键时,他们经常问我:“你做了什么!?” 这不需要太多的努力或智力,但要真正学会它们,我建议每天使用一个快捷键,持续一周,然后再学习下一个。花时间掌握它们是值得的,因为长远来看,您节省的时间将非常可观。
1. “最后一个参数”快捷键:!$
如果您只从本文中选择一个快捷键,那就选择这个。它将上一个命令的最后一个参数替换到您的命令行中。
考虑以下场景
$ mv /path/to/wrongfile /some/other/place
mv: cannot stat '/path/to/wrongfile': No such file or directory
啊,我在命令中输入了wrongfile文件名。我应该输入rightfile才对。
您可能会决定重新输入上一个命令,并将 wrongfile 完全替换为 rightfile。但实际上,您可以输入
$ mv /path/to/rightfile !$
mv /path/to/rightfile /some/other/place
命令就会生效。
在 Bash 中,还有其他方法可以使用快捷键实现相同的效果,但重复使用上一个命令的最后一个参数这个技巧是我最常用的。
2. “第 n 个参数”快捷键:!:2
有没有做过类似的事情?
$ tar -cvf afolder afolder.tar
tar: failed to open
和许多其他人一样,我经常把 tar (和 ln) 的参数搞错,次数多到我自己都不想承认。

当您像这样混淆参数时,您可以运行
$ !:0 !:1 !:3 !:2
tar -cvf afolder.tar afolder
您的声誉将得以保全。
上一个命令的项是零索引的,可以使用 !: 后面的数字进行替换。
显然,您也可以使用它来重用上一个命令中的特定参数,而不是全部参数。
3. “所有参数”快捷键:!:1-$
想象一下,我运行一个像这样的命令
$ grep '(ping|pong)' afile
参数是正确的;但是,我想在一个文件中匹配 ping 或 pong,但我使用的是 grep 而不是 egrep。
我开始输入 egrep,但我不希望重新输入其他参数。因此,我可以使用 !:1$ 快捷键来请求上一个命令的所有参数,从第二个参数(记住它们是零索引的)到最后一个参数(用 $ 符号表示)。
$ egrep !:1-$
egrep '(ping|pong)' afile
ping
您不需要选择 1-$;您可以选择一个子集,例如 1-2 或 3-9(如果您在上一个命令中有那么多参数)。
4. “倒数第 n 个”快捷键:!-2:$
当我知道如何立即更正上一个命令时,上面的快捷键非常棒,但通常我在原始命令之后运行其他命令,这意味着上一个命令不再是我想要引用的命令。
例如,使用前面 mv 的例子,如果我在犯错后使用 ls 检查文件夹的内容
$ mv /path/to/wrongfile /some/other/place
mv: cannot stat '/path/to/wrongfile': No such file or directory
$ ls /path/to/
rightfile
我就不能再使用 !$ 快捷键了。
在这些情况下,我可以在 ! 之后插入 -n:(其中 n 是要回溯历史记录的命令数),以从较旧的命令中获取最后一个参数
$ mv /path/to/rightfile !-2:$
mv /path/to/rightfile /some/other/place
同样,一旦您学会了它,您可能会惊讶于您需要它的频率。
5. “获取文件夹”快捷键:!$:h
这个快捷键表面上看起来不太有前景,但我每天使用它数十次。
想象一下,我运行一个像这样的命令
$ tar -cvf system.tar /etc/system
tar: /etc/system: Cannot stat: No such file or directory
tar: Error exit delayed from previous errors.
我可能想做的第一件事是进入 /etc 文件夹,看看里面有什么,并找出我做错了什么。
我可以通过以下命令一步到位
$ cd !$:h
cd /etc
这个命令的意思是:“获取上一个命令的最后一个参数 (/etc/system),并删除其最后一个文件名组件,只留下 /etc。”
6. “当前行”快捷键:!#:1
多年来,我偶尔会想,是否可以引用当前行上的参数,直到最终查阅并学习了它。我真希望我早点这么做。我最常使用它来创建备份文件
$ cp /path/to/some/file !#:1.bak
cp /path/to/some/file /path/to/some/file.bak
但一旦熟练掌握,它就可以成为 … 的非常快速的替代方案
7. “搜索和替换”快捷键:!!:gs
这个快捷键会在引用的命令中搜索,并将前两个 / 字符中的内容替换为后两个 / 字符中的内容。
假设我想告诉全世界我的 s 键坏了,输出的是 f 而不是 s
$ echo my f key doef not work
my f key doef not work
然后我意识到我只是不小心按到了 f 键。要将所有 f 替换为 s,我可以输入
$ !!:gs/f /s /
echo my s key does not work
my s key does not work
它不仅适用于单个字符;我也可以替换单词或句子。
$ !!:gs/does/did/
echo my s key did not work
my s key did not work
试用一下
只是为了向您展示如何组合这些快捷键,您能弄清楚这些指令会输出什么吗?
$ ping !#:0:gs/i/o
$ vi /tmp/!:0.txt
$ ls !$:h
$ cd !-2:h
$ touch !$!-3:$ !! !$.txt
$ cat !:1-$
结论
对于日常命令行用户来说,Bash 可以是一个优雅的快捷键来源。虽然有成千上万的技巧和窍门可以学习,但这些是我最喜欢且经常使用的快捷键。
如果您想更深入地了解 Bash 可以教给您的所有内容,请购买我的书《Learn Bash the hard way》或查看我的在线课程《Master the Bash shell》。
本文最初发布在 Ian 的博客 Zwischenzugs.com 上,并已获得许可重复使用。
12 条评论