Windows рекурсивная командная строка grep

205

Мне нужно сделать рекурсивный grep в Windows, что-то вроде этого в Unix / Linux:

grep -i 'string' `find . -print`

или более предпочтительный метод:

find . -print | xargs grep -i 'string'

Я застрял только с cmd.exe, поэтому у меня есть только встроенные команды Windows. К сожалению, я не могу установить Cygwin или какие-либо сторонние инструменты, такие как UnxUtils, на этот сервер. Я даже не уверен, что смогу установить PowerShell. Любые предложения, использующие только встроенные модули cmd.exe (Windows 2003 Server)?

Энди Уайт
источник
Это сложно без PowerShell, почему вы не можете установить?
Крис Балланс
Системные администраторы блокируют разрешения на наших серверах. Если у кого-то есть предложения PowerShell, выкиньте их, и я посмотрю, сможем ли мы установить PowerShell.
Энди Уайт
3
Кстати, я обнаружил, что в Linux лучше написать: «найти. | xargs grep -i string». Разница в том, что если find возвращает очень длинный список, вы можете превысить максимальную длину команды (это случилось со мной), и вы вообще не сможете выполнять grep. с xargs grep вызывается один раз для каждого найденного файла.
Натан Феллман
Многие версии Grep, в том числе Gnu Grep, предлагают встроенный рекурсивный поиск ( gnu.org/software/grep/manual/… ), поэтому ваш поиск можно записать так grep -i 'string' -R ., чтобы, как предлагает @NathanFellman, избежать проблемы слишком длинных команд.
Скотт Чентони

Ответы:

253

findstr может выполнять рекурсивный поиск (/ S) и поддерживает некоторый вариант синтаксиса регулярных выражений (/ R).

C:\>findstr /?
Searches for strings in files.

FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:file]
        [/C:string] [/G:file] [/D:dir list] [/A:color attributes] [/OFF[LINE]]
        strings [[drive:][path]filename[ ...]]

  /B         Matches pattern if at the beginning of a line.
  /E         Matches pattern if at the end of a line.
  /L         Uses search strings literally.
  /R         Uses search strings as regular expressions.
  /S         Searches for matching files in the current directory and all
             subdirectories.
  /I         Specifies that the search is not to be case-sensitive.
  /X         Prints lines that match exactly.
  /V         Prints only lines that do not contain a match.
  /N         Prints the line number before each line that matches.
  /M         Prints only the filename if a file contains a match.
  /O         Prints character offset before each matching line.
  /P         Skip files with non-printable characters.
  /OFF[LINE] Do not skip files with offline attribute set.
  /A:attr    Specifies color attribute with two hex digits. See "color /?"
  /F:file    Reads file list from the specified file(/ stands for console).
  /C:string  Uses specified string as a literal search string.
  /G:file    Gets search strings from the specified file(/ stands for console).
  /D:dir     Search a semicolon delimited list of directories
  strings    Text to be searched for.
  [drive:][path]filename
             Specifies a file or files to search.

Use spaces to separate multiple search strings unless the argument is prefixed
with /C.  For example, 'FINDSTR "hello there" x.y' searches for "hello" or
"there" in file x.y.  'FINDSTR /C:"hello there" x.y' searches for
"hello there" in file x.y.

Regular expression quick reference:
  .        Wildcard: any character
  *        Repeat: zero or more occurrences of previous character or class
  ^        Line position: beginning of line
  $        Line position: end of line
  [class]  Character class: any one character in set
  [^class] Inverse class: any one character not in set
  [x-y]    Range: any characters within the specified range
  \x       Escape: literal use of metacharacter x
  \<xyz    Word position: beginning of word
  xyz\>    Word position: end of word

For full information on FINDSTR regular expressions refer to the online Command
Reference.
Майкл Берр
источник
45
findstr - отличная замена для grep. Я склонен использовать findstr / sinp (рекурсивный, без учета регистра, пропустить двоичные файлы и показывать номера строк)
Стив Роу
5
К сожалению, findstr имеет очень ограниченную поддержку регулярных выражений, согласно документации и шаблонам, которые я пытался использовать.
Джон Кастер
3
Вздохните, доверьте Microsoft добавить новую утилиту (findstr) вместо исправления существующей (find). Если вы хотите, чтобы findstr мог считать строки, используйте это - findstr [options] | find / c / v "" - используйте findstr для сопоставления строк и поиска для их подсчета. Да, find считает, что ни одна строка не соответствует пустой строке, поэтому с / v каждая строка будет соответствовать.
йо
3
Они не хотели ломать существующие конвейеры, которые полагались на нарушенное поведение find.
i_am_jorf
134
findstr /spin /c:"string" [files]

Параметры имеют следующие значения:

  • s = рекурсивный
  • p = пропустить непечатные символы
  • i = без учета регистра
  • n = печатать номера строк

И строка для поиска - это бит, который вы вставляете в кавычки после /c:

i_am_jorf
источник
2
Сожалею. Не могли бы вы добавить пример? Что spin? Это строка текста, чтобы найти? И не используется ли / g или / f для указания файлов? Так что с квадратными скобками?
Wolfpack'08
5
findstr /?объясняет каждый параметр. s = рекурсивный, p = пропустить непечатаемые символы, i = без учета регистра, n = напечатать номера строк. Вам не обязательно все это нужно, но они мне нравятся, и их spinлегко запомнить. Строка для поиска - это бит, который вы вставляете в кавычки после /c:.
i_am_jorf
3
Ох, ха-ха. Я сделал /?, но я на самом деле не знал, что модификаторы были использованы как /spin. Я думал, что они были использованы как /s/p/i/n.
Wolfpack'08
4
Да в общем. Некоторые cmd-программы позволяют вам расслабиться с помощью /s. Это один Не все из них позволяют вам это делать. Вы знаете, CMD очень особенный.
i_am_jorf
2
Однако он распространяется как часть Windows и, таким образом, соответствует первоначальным требованиям к постерам, что можно сделать с помощью cmd.exe, для которого не требуется устанавливать дополнительное программное обеспечение.
i_am_jorf
26

Я только что искал текст с помощью следующей команды, которая перечисляла мне все имена файлов, содержащие мой указанный «текст поиска».

C:\Users\ak47\Desktop\trunk>findstr /S /I /M /C:"search text" *.*
khichar.anil
источник
13

Я рекомендую действительно отличный инструмент:

родные утилиты Unix:

Просто распакуйте их и поместите эту папку в переменную окружения PATH и вуаля! :)

Работает как шарм, и есть гораздо больше, чем просто grep;)

mPrinC
источник
5
@mPrinC В вопросе говорится: «К сожалению, я не могу установить Cygwin или какие-либо сторонние инструменты, такие как UnxUtils, на этот сервер».
Мартин Якубик
7
Проголосовал, потому что это все еще полезно для меня. Также он не требует установки, просто распакуйте его куда-нибудь.
Росди Касим
12

Рекурсивный поиск importслова внутри srcпапки:

> findstr /s import .\src\*
Tonatio
источник
9
for /f %G in ('dir *.cpp *.h /s/b') do  ( find /i "what you search"  "%G") >> out_file.txt
Золотой мальчик
источник
Это похоже на этот ответ здесь serverfault.com/a/506615 , но мне нравится тот факт, что вы передаете ответ в файл. Намного легче потреблять.
Jinglesthula
Просто для справки, с помощью findstr вы получаете выделенные имена файлов в командной строке, и вы не получаете это в текстовом файле (очевидно). Так что не обязательно, чтобы текстовый файл был более полезным форматом.
Мартин Гринуэй
5

Select-Stringработал лучше для меня. Все остальные параметры, перечисленные здесь, например findstr, не работают с большими файлами.

Вот пример:

select-string -pattern "<pattern>" -path "<path>"

примечание : для этого требуется Powershell

Blizz
источник
3

Если у вас установлен Perl, вы можете использовать ack , доступный по адресу http://beyondgrep.com/ .

Энди Лестер
источник