Хорошо, вот ответ на мое конкретное требование. Как отмечалось выше в комментариях, в строке Host
можно указать более одного имени :
Host cheddar.halon.org.uk cheddar halon
Hostname cheddar.halon.org.uk
Очень просто!
Это было бы медленным, так как он считывал бы входной файл несколько раз (один раз для каждого символа в строке, которую вы хотите найти, каждый раз в строках размером этой строки поиска ), но это должно работать с файлами любого size со строками любого размера, используя GNU awk для mult -char RS
иRT
(untested):
awk -v str='search-string-here' '
BEGIN {
lgth = length(str)
RS = sprintf("%*s",lgth,"")
gsub(/ /,".",RS)
for (i=1; i<lgth; i++) {
ARGV[ARGC++] = ARGV[1]
}
}
RT == str {
print "found"
exit
}
' file
Он устанавливает RS в N .
с, где N — длина вашей строки поиска, считывая каждую цепочку из N символов из ввода, начиная с char #1, сравнивая их со строкой поиска и выходя, если текущая N символов из ввода соответствует строке поиска. Если на этом проходе нет совпадений, он делает то же самое снова, но начиная с char #2, и так далее, пока это не будет сделано N раз, и поэтому во входном файле больше нет строк длины N для сравнения со строкой поиска..
Обратите внимание, что в приведенном выше примере выполняется сравнение строк, а не регулярное выражение. Чтобы выполнить сравнение регулярных выражений, вам нужно определить максимальную длину совпадающей строки другим способом, а затем использовать оператор сравнения регулярных выражений ~
вместо ==
, например. если вы знаете, что совпадающая строка во входных данных не может быть длиннее 20 символов, вы можете сделать что-то вроде:
awk -v regexp='search-regexp-here' '
BEGIN {
lgth = 20
RS = sprintf("%*s",lgth,"")
gsub(/ /,".",RS)
for (i=1; i<lgth; i++) {
ARGV[ARGC++] = ARGV[1]
}
}
RT ~ regexp {
print "found"
exit
}
' file
но этот поиск по регулярному выражению имеет некоторые недостатки, которых нет у строкового поиска, о которых вам придется подумать, например. если ваше регулярное выражение поиска включает ^
или $
для границ, вы можете получить ложное совпадение выше, поскольку оно создает границы начала/конца строки вокруг каждого символа, когда читаются длинные строки N -символов -.
Вот простое частичное решение, которое работает, только если есть символ, который не появляется в строке (или регулярном выражении )для поиска, но появляется достаточно часто в строке , так что интервал между вхождениями этого символа всегда умещается в памяти. Например, предположим, что каждая строка представляет собой очень длинный список относительно коротких полей, разделенных точкой с запятой -.
<large-file-with-long-lines.txt tr ';' '\n' | grep 'search-string-here'
Вот другое частичное решение, которое работает, если вхождения всегда начинаются с кратного N символов после начала строки для некоторого фиксированного N. Он используетfold
для переноса строк иag
для многострочного поиска. Известно, что в этом примере вхождения всегда начинаются через 3 *x символов после начала строки.
<large-file-with-long-lines.txt fold -w3 | ag $'cat\ntag\ngag\nact'
Это может быть обобщено для поиска произвольных строк путем повторения поиска для каждого смещения.
<large-file-with-long-lines.txt fold -w3 | ag $'fee\n-fi\n-fo\n-fu\nm|fe\ne-f\ni-f\no-f\num|f\nee-\nfi-\nfo-\nfum'
Обратите внимание, что это может иметь ложные срабатывания, если строка почти присутствует, но с разрывом строки посередине.