2012-04-06 78 views
6

我通常使用这样打开VI与通过文件名

$ find -name testname.c 
./dir1/dir2/testname.c 
$ vi ./dir1/dir2/testname.c 

这恼人再次输入与位置的文件名。

我怎么能做到这一点,只有一步?

我已经试过

$ find -name testname.c | xargs vi 

,但我失败了。

+0

可能重复:http://stackoverflow.com/questions/5955577/bash-automatically-capture-output-of-last -executed-command-into-a-variable – 2012-04-06 03:05:03

+0

这个答案解释了为什么'xargs'解决方案不起作用:[为什么“locate filename | xargs vim“导致奇怪的终端行为?](http://stackoverflow.com/a/8228888/85371) – sehe 2012-04-06 10:14:41

回答

10

使用-exec参数find

$ find -name testname.c -exec vi {} \; 

如果您find回报倍数虽然相匹配,文件将被依次打开。也就是说,当你关闭一个,它会打开下一个。你不会让他们都在缓冲区排队。

为了让他们在缓冲区中的所有开放,使用方法:

$ vi $(find -name testname.c) 

这真的是六,顺便说一句,而不是Vim的,到六往往是时下别名?

+0

添加+而不是\;找到会更好打开多个文件。 +语法由POSIX定义,并且应该可用。 – jordanm 2012-04-06 04:56:13

4

问题是xargs接管所有vi的输入的存在(和,有没有其他办法,然后传递/dev/nullvi,因为另一种方法是通过在文件列表的其余部分),不留下任何方法可以让你与它进行交互。你可能想使用,而不是一个子命令:

$ vi $(find -name testname.c) 

可悲的是有没有简单fcr调用,可你已经运行初始find后你轻松做到这一点,但它是很容易的字符添加到这两个事实结束后的命令。

+0

我可以问你一些事吗?你的意思是'xargs'不仅在本例中传递'。/ dir1/dir2/testname.c'? – 2012-04-08 08:07:12

+0

文件描述符是继承的;通常'vi'从shell的输入中继承它的输入,它的输入是你的终端,但是当你在管道末尾使用'xargs'时,继承的输入就是管线。 'xargs'不想让流水线运行到正在运行的程序上(因为充其量只是传递一个消耗的流水线,最坏的情况是程序会消耗用于'xargs'的输入),所以它会替代'/ dev/null'。 – geekosaur 2012-04-08 08:14:09

3

我最喜欢的解决方案是使用vim本身:

:args `find -name testname.c` 

顺便说一下,VIM已经扩展外壳通配符内置的,所以你可以说

:args **/testname.c 

将在子目录树找到递归。

不还,是Vim在命令行上的文件名完成,因此,如果你知道你真正需要的单个文件,尝试

:e **/test 

,然后按标签(多次)循环任何之间matchin文件名在子目录树中。

1

对于一些比vi $(find -name testname.c)等更强大的功能,以下内容将防止带有空白和其他解释的shell字符的文件名(如果您的文件名中嵌入了换行符,god帮助您)。注射此功能为你的shell环境:

# Find a file (or files) by name and open with vi. 
function findvi() 
{ 
    declare -a fnames=() 
    readarray -t fnames < <(find . -name "$1" -print) 
    if [ "${#fnames[@]}" -gt 0 ]; then 
     vi "${fnames[@]}" 
    fi 
} 

然后使用像

$ findvi Classname.java