Find occurrences of a string in files and display

2019-09-05 02:12发布

问题:

Batch file to search every single subfolder and every single file inside a directory and count the number of times a particular string is present in each file.

Would be useful if output is "filename - count".

Can do find /c "Microsoft" *.txt This works if all the files are in one folder.

How do you make the find loop through all the subfolders and each of its files and display the same result.

Findstr has /s which does that, doesnt work on find.

回答1:

From command line:

for /F "delims=" %G in ('findstr /I /S /M "Microsoft" "%CD%\*.txt"') do @find /I /C "Microsoft" "%~G" | findstr /V /R "^$"

From a batch script:

set "_srch=Microsoft"
for /F "delims=" %%G in ('
       findstr /I /S /M "%_srch%" "%CD%\*.txt"') do (
    find /I /C "%_srch%" "%%~G" | findstr /V /R "^$"
)

Omitting the %CD%\ you will get relative paths.

To get rid of ---------- from find output (command line):

for /F "delims=" %G in ('findstr /I /S /M "Microsoft" "%CD%\*.txt"') do @for /F "tokens=1,*" %H in ('find /I /C "Microsoft" "%~G"') do @echo %I

Resources: type for /?, find /?, findstr /?, set /? or go to An A-Z Index of the Windows CMD command line.



回答2:

No solution using FIND /C reports the number of occurrences of the search string - instead it reports the number of lines that contain at least one occurrence of the search string.

If you truly want to count the number of occurrences, including the possibility of more than one occurrence on a single line, then one solution is to use JREPL.BAT - a pure script (hybrid JScript/batch) text processing command line utility that runs on any Windows machine from XP onward.

@echo off
setlocal
for /r %%F in (*.txt) do (
  set "file=  %%F"
  jrepl "Microsoft" "cnt+=1; false" /l /jmatch /jbeg "cnt=0" /jend "output.WriteLine(lpad(cnt,'         ')+env('file'))" /f "%%F"
)

The above produces a nicely formated and aligned report with left padded counts on the left, followed by the full path of the file name. I used the /L option to do a literal search. I define and use the file variable just in case you run across a file name that contains '. If I pass a string literal instead, then all ' would have to be doubled.

If you want to suppress files with 0 count, then you can simply add an if statement:

@echo off
setlocal
for /r %%F in (*.txt) do (
  set "file=  %%F"
  jrepl "Microsoft" "cnt+=1; false" /l /jmatch /jbeg "cnt=0" /jend "if (cnt) output.WriteLine(lpad(cnt,'         ')+env('file'))" /f "%%F"
)

The beauty of using JREPL is you can easily remove the /L option and switch to using a regular expression, and be very specific as to what strings you are searching for.



回答3:

for /R %%i in (*.txt) do find /c "Microsoft" "%%i"

if you want to suppress files with count 0, just add |findstr /v " 0$"

to get rid of the ----------:

for /f "tokens=1,*" %%a in ('for /R %%i in (*.txt^) do find /c "Microsoft" "%%i"^|findstr /v " 0$"') do echo %%b

(delete ^|finstr /v " 0$" if you want to include files with count=0)

This runs about 30% faster than JosefZ's answer.