4

Я ищу все файлы, содержащие определенную строку в файлере (на старой рабочей станции HP-UX).

Я не знаю, где файлы находятся в файловой системе (есть много каталогов, с большим количеством сценариев, текстовых и двоичных файлов).

Я уточняю, что опция grep -R не существует в этой системе; поэтому я использую команды find и grep, чтобы узнать, какие файлы содержат мою строку:

find . -type f -exec grep -i "mystring" {} \;

Я не удовлетворен этой командой: она слишком медленная и не печатает имя и путь к файлу, в котором grep соответствует моей строке. Более того, если есть ошибка, она будет отражена на моем выводе консоли.

Поэтому я подумал, что мог бы сделать лучше:

find . -type f -exec grep -l -i "mystring" {} 2>/dev/null \;

Но это очень медленно.

У вас есть более эффективная альтернатива этой команде?

Спасибо вам.

2 ответа2

2

Самое быстрое, что я могу придумать, это использовать xargs для распределения нагрузки:

find . -type f -print0  | xargs -0 grep -Fil "mypattern" 

Выполнение некоторых тестов в каталоге, содержащем 3631 файл:

$ time find . -type f -exec grep -l -i "mystring" {} 2>/dev/null \;

real    0m15.012s
user    0m4.876s
sys     0m1.876s

$ time find . -type f -exec grep -Fli "mystring" {} 2>/dev/null \;

real    0m13.982s
user    0m4.328s
sys     0m1.592s


$ time find . -type f -print0  | xargs -0 grep -Fil "mystring" >/dev/null 

real    0m3.565s
user    0m3.508s
sys     0m0.052s

Другими вашими вариантами было бы упростить любой из них, ограничив список файлов, используя find:

   -executable
          Matches files which are executable and  direc‐
          tories  which  are  searchable (in a file name
          resolution sense).  
   -writable
          Matches files which are writable.             

   -mtime n
          File's  data was last modified n*24 hours ago.
          See the comments for -atime to understand  how
          rounding  affects  the  interpretation of file
          modification times.
   -group gname
          File  belongs to group gname (numeric group ID
          allowed).
   -perm /mode
          Any  of  the  permission bits mode are set for
          the file.  Symbolic modes are accepted in this
          form.  You must specify `u', `g' or `o' if you
          use a symbolic mode. 
   -size n[cwbkMG]  <-- you can set a minimum or maximum size
          File uses n units  of  space.  

Или путем настройки grep:

Вы уже используете опцию grep -l которая приводит к печати имени файла и, что более важно, останавливается при первом совпадении:

   -l, --files-with-matches
       Suppress normal output; instead print the name of each input file  from
       which  output would normally have been printed.  The scanning will stop
       on the first match.  (-l is specified by POSIX.)

Единственное, что я могу придумать, чтобы ускорить процесс, это убедиться, что ваш шаблон не интерпретируется как регулярное выражение (как предложено @suspectus) с помощью опции -F .

1

Используйте grep -F , который говорит grep интерпретировать шаблон как строку, а не как регулярное выражение (которое, я полагаю, вам не требуется). Это может быть значительно быстрее, чем grep - в зависимости от размера анализируемых файлов.

В Ubuntu и RHEL Linux опция -H будет отображать путь к файлу с соответствующим файлом.

find . -type f -exec grep -FHi "mystring" {} +

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