Поиск строки в нескольких файлах без использования регулярных выражений?

Я думаю, это делает то, что вы хотите:

  zmodload zsh/complist
  setopt menucomplete
  zstyle ':completion:*' menu select=0 search

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

Вас также может заинтересовать такая же конфигурация, но с интерактивом вместо поиска. В этом случае, когда вы вводите, он будет отфильтровывать завершения только те, которые соответствуют тому, что вы набрали до сих пор.

1
11.09.2020, 21:15
2 ответа

Если файлы являются текстовыми и строка не содержит символов новой строки, вы можете использовать grepс опцией-F(для фиксированной строки -).

string='any /text\ *string* without newline (\n).'
find. -type f -exec grep -F -l -e "$string" {} +

Список текстовых файлов, содержащих строку, содержащую эту строку.

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

Некоторые grepреализации могут также работать с не -текстовыми файлами (, такими как те, которые содержат NUL, байты, с слишком длинными строками или последовательностями байтов и не формируют допустимые символы в вашей локали ). Некоторые также могут выполнять работу findс параметрами -r, -R, -d recurse, хотя есть некоторые различия в поведении, когда речь идет о не -обычных файлах или о том, используются ли символические ссылки на каталоги, когда спуск по дереву каталогов.

В busyboxреализации grepвы можете заставить его работать со строками текста, содержащими символы новой строки, с помощью опции -z. -zдолжен работать с записями с разделителями NUL -вместо строк, но текстовые файлы по определению не могут содержать NUL, и в любом случае вы не можете передать NUL в аргументе команде или (, кроме как вzsh)хранилище их в переменной оболочки, такой как $string.

Так:

string='1
2
3'
busybox grep -raFlze "$string".

Будет работать для произвольных строк на любом входе. Однако обратите внимание, чтоbusybox grep -r(по крайней мере, текущие версии ), ищите в файлах любого типа, включая символические ссылки, устройства...поэтому вы можете использовать findвместо его -r, чтобы ограничиться только обычными файлами:

find. -type f -exec grep -aFlze "$string" {} +

(некоторые findреализации также имеют -xtype fдля проверки типа файла после разрешения символической ссылки для поиска внутри символических ссылок на обычные файлы ).

Если входные файлы не содержат байты NUL, это означает, что каждый файл загружается целиком в память, поэтому он плохо масштабируется для очень больших файлов.

Для произвольных данных, содержащих, возможно, NUL и файлы любого размера, вы можете сохранить строку для поиска в файле и использовать mmap(), чтобы избежать загрузки файлов в память. С perlвы можете сделать что-то вроде:

needle_file=needle.bin # containing the string to search
size=$(wc -c < "$needle_file")

find. -type f -size "+$(( size - 1 ))c" -exec perl -MSys::Mmap -le '
  $needle = shift;
  open NEEDLE, "<", $needle or die "$needle: $!\n";
  mmap($needle, 0, PROT_READ, MAP_SHARED, NEEDLE);
  for (@ARGV) {
    if (open HAYSTACK, "<", $_) {
      mmap($haystack, 0, PROT_READ, MAP_SHARED, HAYSTACK);
      print if index($haystack, $needle) >= 0
    } else {
      warn "$_: $!\n"
    }
  }' -- "$needle_file" {} +

(обратите внимание, что Sys::Mmapне является одним из основных модулей perl, возможно, вам придется установить его из пакета libsys-mmap-perlв Debian ).

Я не могу сказать, насколько эффективен perlалгоритм поиска подстроки index()при поиске подстрок.

zshможет хранить значения NUL в своих переменных и может сопоставлять содержимое файлов с переменными, поэтому вы можете сделать что-то вроде:

zmodload zsh/mapfile
set +o multibyte
string=$'foo\nbar\0baz'
print -rC1 -- **/*(ND.L+$(($#string - 1))e['[[ $mapfile[$REPLY] = *$string* ]]'])

Но обратите внимание, что хотя zshиспользует mmap()внизу, он также копирует содержимое файла в память, и это оболочка, я сомневаюсь, что она была оптимизирована до такой же степени, как язык программирования. например perl.

3
18.03.2021, 23:05

А как насчет:

grep -inH -r "search_string" *
0
18.03.2021, 23:05

Теги

Похожие вопросы