Tip: #354 - Find in files recursively
Created: October 30, 2002 4:31 Complexity: basic Author: Karthick Gururaj Version: 5.7 Karma: 19/12 Imported from: Tip#354
You probably know about the grep command in vim (:help grep)
There is one limitation of this - you can't search for a pattern recursively in files (why doesn't grep have some kind of -R option for searching recursively? Have looked around enough at the man pages for that..). The script below does this. Cut-paste this in to your .vimrc/_vimrc. Type ":Fif" (without arguments) to see usage.
" Start of script
" Location where the temporary file (.fif.tmp) would be stored
let g:Fif_tmp_dir = "/tmp"
function! Fif_fun(...)
if a:0 == 0
" Print usage info and quit
echo "Usage: Fif <pattern-to-be-searched> <file-pattern>. E.g:"
echo "Fif struct *.c"
echo "searches for the word struct in all the c files from the current directory"
return
endif
if a:0 != 2
echohl Error
echo "Error! Wrong number of arguments. Type :Fif with no arguments to see usage"
echohl None
return
endif
let tmp_file = g:Fif_tmp_dir . "/.fif.tmp"
execute "!touch " . tmp_file . " 2> /dev/null"
if ! filewritable(tmp_file)
echohl Error
echo "No permissions to create " . tmp_file
echo "Try setting the g:Fif_tmp_dir variable to the right value"
echohl None
return
endif
" Put quotes around the file pattern
let com_string = '!find . -name "' . a:2 . '" '
" Do NOT put quotes around the pattern to be searched - leave it to the user
let com_string = com_string . '-exec grep -n ' . a:1 . ' /dev/null {} \; > ' . tmp_file
execute com_string
if ! filereadable(tmp_file)
echohl Error
echo "Can't open " . tmp_file . " for reading"
echohl None
return
endif
execute "cfile " . tmp_file
execute '!rm -f ' . tmp_file . ' 2> /dev/null'
endfunction
com -nargs=* Fif call Fif_fun(<f-args>)
" End of script.
No vim magic here, just some shell util usage.
Tested on HPUX.
Should work on Windows with Cygwin. You'll have to
1. Remove those /dev/null's
2. Make sure that the Cygwin's find and grep utils are used, and not the windows ones
3. Change the default value of g:Fif_tmp_dir
4. Cygwin's grep differs from the version I have on HP. For forcing grep to print the filename, you'll have to give it a "-H" option, in addition to "-n"
Some more tinkering can be done with this.. for instance, if you want to search in all the text files, irrespective of the extention, you can consider doing something like this:
" Find all files.
let com_string = '!find . -type f -print '
" Get the file type
let com_string = com_string . '
Comments
I don't know about grep on HP-UX, but GNU grep *can* recurse into directories using either the "-d recurse", or "--recursive" options.
ctechols--AT--mindspring.com , October 30, 2002 4:55
Mea culpa. Maxima culpa. The version of grep I have in HP does *not* have the "-d recurse" feature, but yes, the GNU grep has, and I have the GNU grep now. Thanks for the information.
- Karthick. PS: Is there a way to remove a tip from these archives?
stonnedsnake--AT--yahoo.com , October 30, 2002 21:05
You can even abbreviate that as -r for GNU grep. I often do something like
grep -r 'some_func(' .
Really convenient.
Anonymous , November 16, 2002 18:02
or, if you can't get GNU grep (which you should) you can always use:
find . | xargs grep whatever
shawn at deleurme dot calm.
, June 13, 2003 12:57
Or, from within vim:
- grep whatever `find . -name "*.cpp"`
or whatever
scottu--AT--apptechsys.com , June 18, 2003 13:21
Give this a try.
- grep -i "looking for someting" *.c */*.c *.h */*.h */*/*.h
I think this could work for you, unless I am missunderstanding the problem.
~rs3
Anonymous , August 25, 2003 13:38