Я думаю, это делает то, что вы хотите:
zmodload zsh/complist
setopt menucomplete
zstyle ':completion:*' menu select=0 search
Это приведет к тому, что список появится, когда вы нажмете клавишу Tab, а затем, если вы продолжите печатать, он будет искать доступные параметры, включая описания, с пошаговым поиском.
Вас также может заинтересовать такая же конфигурация, но с интерактивом вместо поиска. В этом случае, когда вы вводите, он будет отфильтровывать завершения только те, которые соответствуют тому, что вы набрали до сих пор.
Если файлы являются текстовыми и строка не содержит символов новой строки, вы можете использовать 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
.