4

When I use grep to find some text which I need, it will display lines containing a match to the given pattern.

For example,

# grep -r ".*Linux" *
path0/output.txt:I hope you enjoyed working on Linux.
path1/output1.txt:Welcome to Linux.
path2/output2.txt:I hope you will have fun with Linux.

then, I want to edit the file path2/output2.txt, hence, I type vim path2/output2.txt.

But, I don't think it is an effective way.

How can I copy the path after grep?

3
  • That's on the top of wishlists by the way; tab completion for things used in the last command: i.e. the files outputed by grep in the last command, or the files used in the last command. Commented Aug 24, 2013 at 9:35
  • Please keep feature requests to the upstream project. Also contact the vendor for your support options first. No need to drive attention away from the original project(s).
    – hakre
    Commented Aug 24, 2013 at 9:48
  • @Erik Johansson: Isn't there a bash command to shedule for the next commands tabbing?
    – hakre
    Commented Aug 24, 2013 at 9:50

4 Answers 4

6

These are safe ways to find all files with Linux (lower and upper case).

xargs -a <(grep -rlZi Linux *) -0 vim
grep -rlZi Linux *| xargs -0 sh -c 'vim "$@" < /dev/tty' vim
grep -rlZi Linux *| xargs -0 vim # you need to run reset after this command 

There are differences between GNU xargs and BSD xargs so might not work on MacOSX.

  • -Z and -0 options are for NULL delimited filenames
  • -l for outputting the filenames of the files that match.
  • -i match lower and uppcase.
  • -o on bsd xargs will do the same as the "sh -c" part
2
  • Using vim with xargs may result in the warning, Vim: Warning: Input is not from a terminal, and a messed up terminal.
    – user26112
    Commented Aug 24, 2013 at 15:27
  • True, bsd xargs has a -o options, I've supplied a fix from GNU xargs man page above. Commented Aug 29, 2013 at 11:44
6
vim `grep -r ".*Linux" * | cut -f1 -d":"`

backticks are for command substitution. | is for piping output of grep to cut. -d":" says cut based on delimited :. -f1 says the first field after cutting.

1
  • 4
    Just a note: backtics are deprecated. $(command) should be used instead..
    – hek2mgl
    Commented Aug 24, 2013 at 9:24
3

You can nest your grep command in as an argument to vim .... The grep command will produce the list of files all as a single argument to vim, when it get's expanded. Also you can simplify your search criteria to just ' Linux' for the examples you've given, it's not necessary to include the .* wildcard.

List of files

This command will generate the list of files for vim.

$ grep -lr ' Linux' *
path0/output.txt
path1/output1.txt
path2/output2.txt

You can nest this inside of a command substitution block ($(..)), like so:

$(grep -lr ' Linux' *)

You can use echo to see what this list will end up looking on the command line when passed to vim:

$ echo $(grep -lr ' Linux' *)
path0/output.txt path1/output1.txt path2/output2.txt

Putting it all together

$ vim $(grep -lr ' Linux' *)
3 files to edit
...

With this approach you just need to be careful if your list of files is going to be extremely long. But in general this is highly unlikely.

2

Good editors let you run grep inside.

In Vim, run :grep -r ".*Linux" .

In Emacs, run M-x grep and type ".*Linux" -r .

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .