Sungguk Lim
Sungguk Lim

Reputation: 6228

open vi with passed file name

I usually use like this

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

it's to annoying to type file name with location again.

how can I do this with only one step?

I've tried

$ find -name testname.c | xargs vi 

but I failed.

Upvotes: 6

Views: 2242

Answers (5)

Reed Sandberg
Reed Sandberg

Reputation: 741

For something a bit more robust than vi $(find -name testname.c) and the like, the following will protect against file names with whitespace and other interpreted shell characters (if you have newlines embedded in your file names, god help you). Inject this function into your shell environment:

# 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
}

Then use like

$ findvi Classname.java

Upvotes: 1

sehe
sehe

Reputation: 393769

My favorite solution is to use vim itself:

:args `find -name testname.c`

Incidentally, VIM has extended shell globbing builtin, so you can just say

:args **/testname.c

which will find recursively in the sub directory tree.

Not also, that VIM has filename completion on the commandline, so if you know you are really looking for a single file, try

:e **/test

and then press Tab (repeatedly) to cycle between any matchin filenames in the subdirectory tree.

Upvotes: 3

K Z
K Z

Reputation: 30483

You can do it with the following commands in bash:

Either use

vi `find -name testname.c` 

Or use

vi $(!!)

if you have already typed find -name testname.c

Edit: possible duplication: bash - automatically capture output of last executed command into a variable

Upvotes: 6

geekosaur
geekosaur

Reputation: 61459

The problem is xargs takes over all of vi's input there (and, having no other recourse, then passes on /dev/null to vi because the alternative is passing the rest of the file list), leaving no way for you to interact with it. You probably want to use a subcommand instead:

$ vi $(find -name testname.c)

Sadly there's no simple fc or r invocation that can do this for you easily after you've run the initial find, although it's easy enough to add the characters to both ends of the command after the fact.

Upvotes: 4

Michael Berkowski
Michael Berkowski

Reputation: 270757

Use the -exec parameter to find.

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

If your find returns multiple matches though, the files will be opened sequentially. That is, when you close one, it will open the next. You won't get them all queued up in buffers.

To get them all open in buffers, use:

$ vi $(find -name testname.c)

Is this really vi, by the way, and not Vim, to which vi is often aliased nowadays?

Upvotes: 9

Related Questions