1

I once had a version of grep on my PC (I think it came with an early version of Delphi) which supported searching in nested folders with the -r switch. Now something (I suspect a later version of Delphi) has hijacked the old grep and replaced it with something that announces itself thus:

C:\PROJECTS\>grep --version
grep (GNU grep) 2.4.2

Copyright 1988, 1992-1999, 2000 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

it provides these options for recursion:

-d, --directories=ACTION  how to handle directories
                          ACTION is 'read', 'recurse', or 'skip'.
-r, --recursive           equivalent to --directories=recurse.

but I can't make it return results from files within folders, so grep -r fred *.txt will only find files in the current folder containing "fred", and files within subfolders are ignored.

What's the magic option required here?

ANSWER from Rich Homolka is below, but here's my batch wrapper developed from that answer:

:==========================================================================
:   GrepExt - searches files matching an extension recursively for a string 
:
:   Usage   : call GrepExt <regex string to search for>  <extension>
:   Example : call GrepExt "procedure\ *Add" pas
:
:   Notes   : - quotes only needed if regex contains spaces
:             - remove the first "-i" for case-sensitive search 
:             - the second "-i" ensures the case of the extension doesn't matter     
:             - ErrorLevel set to 0 if there were any matches, 1 otherwise
:             - this is very inefficient when the folders contain a large
:               number of files that don't match the extension, as *all* files
:               are grepped and the results are then grepped to filter out
:               the hits from files that don't match the extension.         
:
@echo off
grep -i -r "%~1" . | grep -i "^[^:]*\.%~2:"
Oliver Salzburg
  • 89,072
  • 65
  • 269
  • 311
rossmcm
  • 1,656

2 Answers2

3

Grep is probably working right. Your command is what's off. I answered something similar before here, regarding chown on UNIX, with a UNIX shell. Some of the explanation may be useful.

If you want to check using the recursive flag, you want to pass a directory:

grep -r fred .

This will find fred in any files rooted at ., named *.txt or not.

If you want to limit this to just files named *.txt, you could do this a bit with grep itself:

grep -r fred . | grep '^[^:]*\.txt:'

This is obviously a bit clumsy to type every time, but works.

A cleaner way is to use a UNIX style shell (or at least it's too hard to do in command prompt, I don't how to do so).

In unix, for recursive commands, you commonly use the pattern

find file_selection_criteria | xargs command whatever_args

In this case would be:

find . -name '*.txt' | xargs grep fred

As a simpler thing, if you downloaded a fairly recent shell like bash4 or zsh you could use the new recursive glob (double *):

shopt -s globstar # needed for bash4
grep fred ./**/*.txt

So it really depends on how much work you'd want to do. If you want to just have grep work now, maybe you use the first one, and filter out anything not named .txt. If you do this often, maybe the time invested in getting a UNIX like shell is worth it. You can get one from Cygwin or use a tool or two from MinGW

Rich Homolka
  • 32,350
0

you could use the native find command inside a for loop for the same purpose:

for /r c:\users\administrator\desktop %a in (*) do @find /i /n "foo" %a

here starting from the directory c:\users\administrator\desktop it will recursively (/r) search for the string foo in all (*) files incase-sensitively (/i) alongside displaying their line numbers (/n) if found