3

I want to find out all the files which contain a keyword in a directory and all the subdirectories, and there are some .svn directories, I should ingore these directories.

In Linux system, I can do it easily by:

  grep -r keyword ./ --exclude-dir ".svn"

But when I turn to windows, findstr is a substitute for grep in windows, I try to do it like this:

  findstr /s keyword ./*

The result will return with the .svn directories, which is not what I want.

I read the TN Findstr, on microsoft website

  /v   : Prints only lines that do not contain a match.

But when I try it like below, It still doesn't work.

 findstr /s keyword /v ".svn" ./*

I think there may be some problem with my usage of findstr. Any help would be great, thanks in advance.

        ***************************** update1 *****************************

In fact, I am trying to use grep in GVim, it will call 'findstr`.

srain
  • 8,944
  • 6
  • 30
  • 42

4 Answers4

2

AFAIK you can't exclude specific (sub)folders in findstr. In PowerShell you could do something like this, though:

$root = '.'
$keyword = 'keyword'

Get-ChildItem $root -Recurse -Force | ? {
  -not $_.PSIsContainer -and $_.FullName -notlike "*\.svn*"
} | Select-String $keyword -AllMatches

Or you could make use of the fact that .svn subfolders are hidden and do this:

$root = '.'
$keyword = "keyword"

Get-ChildItem $root -Recurse | ? { -not $_.PSIsContainer } |
    Select-String $keyword -AllMatches

This won't work, though, if some of the files that you want to search through have the hidden attribute set.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • I wonder if they have fixed the `Get-ChildItem -Exclude` switch in PowerShell 3 so you don't have to use the filter. I can't test that where I am right now. – dan-gph Jul 29 '13 at 08:45
  • In fact, I am trying to use grep in `GVim`, it will call 'findstr`. – srain Jul 29 '13 at 08:52
  • @srain Then don't use `grep`? – Ansgar Wiechers Jul 29 '13 at 09:04
  • `grep` will call outer program `findstr` in `gvim`. Do you mean `set grepprg` to [`Grep for Windows`](http://gnuwin32.sourceforge.net/packages/grep.htm)? This would be a good way to use `grep` in `gvim`. But, I intend to do this job by using `findstr` or other dos tool. – srain Jul 29 '13 at 09:11
  • Yes, that might help. – Ansgar Wiechers Jul 29 '13 at 09:14
  • @AnsgarWiechers, do you think there is a way to do this job by using `findstr` or other dos tools? – srain Jul 29 '13 at 09:21
1

This should work, assuming your files do not return .svn\ in the content.

 findstr /s "keyword" * |findstr /v /i /L ".svn\"
foxidrive
  • 40,353
  • 10
  • 53
  • 68
  • That will not work with VIM's "grepprg" setting, which requires an "open" command line (like `findstr /s`; the keyword and file pattern is appended by VIM). You could/would have to wrap that in a batch file and use that from VIM. – Christian.K Jul 30 '13 at 05:23
  • @Christian.K Vim allows to specify where it puts the arguments via `$*`; see `:help 'grepprg'`. – Ingo Karkat Jul 30 '13 at 06:36
  • @IngoKarkat Oh, I missed that, thanks. But I think using a pipe still doesn't work (well at least I was unable to make it work ;-) – Christian.K Jul 30 '13 at 06:39
  • @Christian.K The pipe needs to be properly escaped, as it's also a Vim command separator. – Ingo Karkat Jul 30 '13 at 06:40
  • @IngoKarkat Indeed. But what is the proper escaping in this case? This `:set grepprg=findstr\ /s\ $*\ \ \|\ findstr\ /v\ /i\ /L\ ".svn\\"`, i.e. a simple `"\|"` doesn't seem to work. VIM only considers the left side of the pipe as the external command. – Christian.K Jul 30 '13 at 07:15
  • 1
    @Christian.K Yes, escaping (both for Vim and the Windows command prompt) isn't trivial. This seems to work: `:set grepprg=findstr\ /s\ $*\ \ ^\\\|\ findstr\ /v\ /i\ /L\ ".svn\\"` – Ingo Karkat Jul 30 '13 at 08:01
  • @Christian.K, I tested, the `findstr` after pipe still seems not to work. Does it work for you? – srain Jul 31 '13 at 03:36
  • 1
    It seems to work (at least syntax wise) when you add escape the quotes around the `.svn` as well: `:set grepprg=findstr\ /s\ $*\ \ ^\\\|\ findstr\ /v\ /i\ /L\ \".svn\\\"` – Christian.K Jul 31 '13 at 05:47
  • @Christian.K , If I want to match `.svn\ `, I should add escape the slash after `svn`, the vim `set grepprg` will be: `:set grepprg=findstr\ /s\ $*\ \ ^\\\|\ findstr\ /v\ /i\ /L\ \".svn\\\\\"`. Thank you for you help again. – srain Jul 31 '13 at 06:46
0

Thanks to @Christian.K's help, I worked this out:

I set grepprg as below:

 :set grepprg=findstr\ /s\ $*\ \ ^\\\|\ findstr\ /v\ /i\ /L\ \".svn\"

The options above only match .svn.If you want to match .svn\ in gvim, you should:

 :set grepprg=findstr\ /s\ $*\ \ ^\\\|\ findstr\ /v\ /i\ /L\ \".svn\\\\\"
srain
  • 8,944
  • 6
  • 30
  • 42
0

Try creating a bat file find.bat that contains this and type find . keyword. You could use a doskey to hide having to type the . if you wanted.

@echo off
SETLOCAL
set curDir=%1
if "%curDir%"=="." set curDir=%cd%
for /f %%i in ('dir /b/a-h-d %curDir% 2^>nul') do findstr /ilmp %2 %curDir%\%%i
for /f %%i in ('dir /b/ad-h %curDir%') do call %0 %curDir%\%%i %2
ENDLOCAL
Christopher King
  • 1,034
  • 1
  • 8
  • 21