如何在命令行中让第二个路径参数相对于第一个路径?
哈哈,这个需求我太懂了!每次敲长路径敲两遍真的超烦躁,尤其是要在同一个目录里复制、对比文件的时候,重复输入完全是浪费时间嘛。其实shell里有几个实用的小技巧,能帮你省去重复敲路径的麻烦,我给你整理几个常用的:
用shell历史参数快速取目录(bash最顺手)
这是我平时用得最多的方法,比如你要执行复制命令,敲完第一个路径后,直接用!$:h来获取它的目录部分,再跟上新文件名就行:cp path/to/the/file.txt !$:h/file.copy这里的
!$代表你刚输入的最后一个参数(也就是第一个路径path/to/the/file.txt),:h是shell的参数扩展标记,用来提取路径的目录部分(相当于去掉最后的文件名)。敲完回车,shell会自动把命令展开成cp path/to/the/file.txt path/to/the/file.copy,完美实现你想要的效果!要是你在敲命令的中途就想补全,还可以用
!#:1:h——!#代表当前正在输入的命令,:1指代第一个参数,比如:cp path/to/the/file.txt !#:1:h/file.copy还没敲回车,shell就会帮你补全好路径,效率拉满。
脚本场景用dirname命令(更稳定)
要是你写脚本,或者想要更清晰的写法(避免历史参数的歧义),可以用dirname命令提取目录,再拼接新文件名:cp path/to/the/file.txt "$(dirname path/to/the/file.txt)"/file.copy这个写法虽然要多打一遍原路径,但胜在逻辑清晰,脚本里用不会出问题,完全不依赖shell的历史记录。
zsh用户的专属简化操作
如果你用的是zsh(现在很多开发者都转用zsh了),还有更丝滑的语法:比如直接用参数扩展快速修改文件名。要是你想把原文件名的后缀改掉,比如从file.txt改成file.copy,可以这么写:cp path/to/the/file.txt !#:1:s/.txt/.copy/这里的
s/.txt/.copy/就是把第一个参数里的.txt替换成.copy,连目录带文件名一起改,比敲新名字还快!
举个你提到的diff场景的例子,原来要敲diff path/to/really/long/dir/file1.txt path/to/really/long/dir/file2.txt,现在只用敲:
diff path/to/really/long/dir/file1.txt !$:h/file2.txt
瞬间省了一大串路径的输入,是不是爽多了!
备注:内容来源于stack exchange,提问作者RoadRoller01

