1

Однажды у меня была версия grep на моем ПК (я думаю, что она шла с ранней версией Delphi), которая поддерживала поиск во вложенных папках с ключом -r . Теперь кое-что (я подозреваю более позднюю версию Delphi) взломало старый grep и заменило его чем-то, что объявляет себя таким образом:

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.

он предоставляет следующие опции для рекурсии:

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

но я не могу заставить его возвращать результаты из файлов в папках, поэтому grep -r fred *.txt будет искать только файлы в текущей папке, содержащей "fred", а файлы в подпапках игнорируются.

Какая магическая опция требуется здесь?

ОТВЕТ от Rich Homolka ниже, но вот мой пакетный упаковщик, разработанный из этого ответа:

:==========================================================================
:   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:"

2 ответа2

3

Grep, вероятно, работает правильно. Ваша команда это то, что выключено. Я ответил что - то подобное прежде , чем здесь, в отношении Чаун на UNIX, с оболочкой UNIX. Некоторые объяснения могут быть полезны.

Если вы хотите проверить, используя рекурсивный флаг, вы хотите передать каталог:

grep -r fred .

Это найдет fred в любых файлах с корнем в., Названных * .txt или нет.

Если вы хотите ограничить это только файлами с именем * .txt, вы можете сделать это немного с помощью самого grep:

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

Это, очевидно, немного неуклюже печатать каждый раз, но работает.

Более чистый способ - использовать оболочку в стиле UNIX (или, по крайней мере, это слишком сложно сделать в командной строке, я не знаю, как это сделать).

В Unix для рекурсивных команд вы обычно используете шаблон

find file_selection_criteria | xargs command whatever_args

В этом случае будет:

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

Проще говоря, если вы загрузили довольно новую оболочку, такую как bash4 или zsh, вы можете использовать новый рекурсивный глоб (double *):

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

Так что это действительно зависит от того, сколько работы вы хотели бы сделать. Если вы хотите просто запустить grep сейчас, возможно, вы используете первый и отфильтруете все, что не называется .txt. Если вы делаете это часто, возможно, время, потраченное на получение оболочки типа UNIX, того стоит. Вы можете получить один из Cygwin или использовать инструмент или два из MinGW

0

Вы можете использовать команду родную find внутри for цикла для тех же целей:

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

здесь, начиная с каталога c:\users\administrator\desktop он будет рекурсивно (/r) искать строку foo во всех (*) файлах с учетом регистра (/i) наряду с отображением номеров строк (/n), если они найдены

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .