我想构造一个简短的函数来执行以下操作。假设我将文件“file.tex”移动到我的文档目录:
mv file.tex ~/Documents
然后,我想cd
进入该目录:
cd ~/Documents
我想将其推广到任何目录,以便我可以这样做:
mv file.tex ~/Documents
follow
并让follow
命令从前一个命令读取目标,然后相应地执行。对于一个简单的目录,这并不能节省太多时间,但是当使用嵌套目录时,如果能够使用
mv file.tex ~/Documents/folder1/subfolder1
follow
我认为这会相对简单,我可以做这样的事情:
follow()
{
place=`history 2 | sed -n '1p;1q' | rev | cut -d ' ' -f1 | rev`
cd $place
}
但这似乎不起作用。如果我 echo $place
,我确实得到了所需的字符串(我正在使用 测试它~/Documents
),但最后一个命令返回
No such file or directory
该目录确实存在。我不知所措。你能帮我一下吗?
答案1
您可以使用变量 来代替定义函数,$_
该变量通过 扩展为上一个命令的最后一个参数bash
。所以使用:
cd "$_"
mv
命令后。
您也可以使用历史扩展:
cd !:$
如果必须使用函数:
follow () { cd "$_" ;}
$ follow () { cd "$_" ;}
$ mv foo.sh 'foo bar'
$ follow
foo bar$
注意:这个答案针对的是您在处理位置参数时使用的确切命令行参数格式。对于其他格式,例如mv -t foo bar.txt
,您需要事先合并特定的检查,那么包装器就合适了。
答案2
使用标准 bash 键绑定,该组合Alt.会将上一个命令行的最后一个参数复制到当前命令行中。所以,输入
$ mv foo ~/some/long/path/
$ cd <Alt><.>
会产生
$ mv foo ~/some/long/path/
$ cd ~/some/long/path/
甚至比单词 还要少打字follow
。
为了更加方便,重复Alt.组合将浏览所有先前命令行的最后一个参数。
附录:该组合键对应的 bash 命令名称为yank-last-arg
或insert-last-argument
。它可以在 bash 联机帮助页的“Commands for Manipulated the History”下找到,或者在更详尽的Bash 参考手册.)
答案3
您几乎肯定会遇到波浪线扩展发生在参数扩展之前的问题,这可以通过一个简洁的示例来解释:
$ cd ~kaz
kaz $ var='~kaz'
kaz $ echo $var
~kaz
kaz $ cd $kaz
bash: cd: ~kaz: No such file or directory
这可以通过 来解决eval
。无论如何,您将需要eval
,因为您正在从历史记录中提取命令,并且它们可以包含任意扩展,例如:
$ mv file.tex ~/Documents/$(compute_folder_name foo-param)/subfolder1
$ follow
(存在一些问题,例如这些值的重新扩展可能不再与发生的原始扩展匹配。假设compute_folder_name
是一个递增某些全局变量的函数。)