Найти вхождения строки в файлах и отобразить имя файла - подсчет через пакетный файл

Пакетный файл для поиска каждой отдельной подпапки и каждого отдельного файла внутри каталога и подсчета количества раз, когда определенная строка присутствует в каждом файле.

Было бы полезно, если бы вывод был "имя файла - количество".

Можно найти /c "Microsoft" *.txt Это работает, если все файлы находятся в одной папке.

Как сделать цикл поиска по всем подпапкам и каждому из его файлов и отобразить тот же результат.

Findstr имеет /s, который делает это, не работает с поиском.


person macro32    schedule 21.07.2015    source источник
comment
Вам подходит полный путь (начиная с C:\...)?   -  person Stephan    schedule 21.07.2015
comment
Да, Стефан, на самом деле это было бы идеально.   -  person macro32    schedule 21.07.2015
comment
Обратите внимание: FIND /C сообщает количество строк, содержащих искомую строку, а не количество вхождений.   -  person dbenham    schedule 21.07.2015


Ответы (3)


Из командной строки:

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

Из пакетного скрипта:

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

Опустив %CD%\, вы получите относительные пути.

Чтобы избавиться от ---------- из вывода find (командная строка):

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

Ресурсы: введите for /?, find /?, findstr /?, set /? или перейдите к индексу A-Z командной строки Windows CMD.

person JosefZ    schedule 21.07.2015
comment
Этот метод считает строки, а не строки. Если есть строка с несколькими вхождениями строки, она считается как одна. - person Aacini; 03.11.2015

Никакое решение, использующее FIND /C, не сообщает о количестве вхождений строки поиска — вместо этого оно сообщает количество строк, содержащих хотя бы одно вхождение строки поиска.

Если вы действительно хотите подсчитать количество вхождений, включая возможность более одного вхождения в одной строке, то одним из решений является использование JREPL.BAT — чисто скриптовая (гибридная JScript/пакетная) утилита командной строки для обработки текста, которая работает на любом компьютере с Windows, начиная с XP.

@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"
)

Приведенное выше дает хорошо отформатированный и выровненный отчет с добавленными слева счетчиками слева, за которыми следует полный путь к имени файла. Я использовал опцию /L для буквального поиска. Я определяю и использую переменную file на тот случай, если вы встретите имя файла, содержащее '. Если вместо этого я передам строковый литерал, то все ' придется удвоить.

Если вы хотите подавить файлы с нулевым счетчиком, вы можете просто добавить оператор if:

@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"
)

Прелесть использования JREPL заключается в том, что вы можете легко удалить параметр /L и переключиться на использование регулярного выражения, а также очень точно указать, какие строки вы ищете.

person dbenham    schedule 21.07.2015

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

если вы хотите подавить файлы со счетчиком 0, просто добавьте |findstr /v " 0$"

чтобы избавиться от ----------:

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

(удалите ^|finstr /v " 0$", если вы хотите включить файлы с количеством = 0)

Это работает примерно на 30% быстрее, чем ответ JosefZ.

person Stephan    schedule 21.07.2015