Разрешение имен — довольно плохой способ блокирования нежелательного веб-трафика. Список вещей, которые нужно блокировать и не блокировать, постоянно меняется, и иногда вам нужно блокировать по URL, а не только по хосту. Браузерные расширения, такие как AdBlock *и uBlock *, как правило, работают намного лучше. Если вы хотите написать свой собственный список, вы можете написать PAC-файл .
Если вы действительно хотите блокировать запросы на основе доменных имен, делайте это с DNS-прокси, а не с /etc/hosts
. /etc/hosts
может делать только отдельные хосты. Dnsmasq — популярный легкий DNS-прокси. Некоторые дистрибутивы настраивают dnsmasq по умолчанию; большинство дистрибутивов имеют его в виде пакета. Чтобы весь домен отображался как локальный с помощью dnsmasq, вы можете использовать следующую строку в/etc/dnsmasq.conf
:
address=/co.kr/127.0.0.2
#!/bin/sh
pttrn="^$(printf '%s' "$1" | sed -e 's/\(.\)/\1*/g' -e 's/\*/\\+/' -e 's/\*$/\\+/')"'$'
grep "$pttrn" /usr/share/dict/words
Шаблон получается из первого аргумента путем вставки *
после каждого символа. Затем первый *
заменяется на \+
; так и последний *
. Дополнительно добавляются ^
и $
. Ваш пример ввода генерирует следующий шаблон:
^q\+w*e*r*t*y*u*y*t*r*e*s*d*f*t*y*u*i*o*k*n\+$
Этот шаблон является правильным шаблоном для grep
. q
должен появиться хотя бы один раз в начале, n
должен появиться хотя бы один раз в конце. Каждая буква в середине может появляться ноль или более раз, порядок сохраняется.
Обратите внимание, что скрипт тупой. Если вы предоставите ввод с .
, [
, ]
или около того, вы получите регулярное выражение, выходящее за рамки спецификации. Предоставьте разумный ввод или расширьте сценарий, чтобы проверить его.
Примеры:
$./script1.sh qwertyuytresdftyuiokn
queen
question
$./script1.sh te
tee
$./script1.sh superuser
seer
serer
spur
super
supper
surer
$
Вот один из способов приблизиться к этому
Во-первых, отфильтруйте список слов до тех слов, которые начинаются и заканчиваются теми же буквами, что и беспорядок. Например, если беспорядок передается как позиционный параметр$1
(и предполагается недавняя оболочка bash
)
grep -x "${1:0:1}.*${1:(-1):1}" /usr/share/dict/words
Затем возьмите каждое из этих слов и превратите их в регулярное выражение. -Я не могу придумать "хорошего" способа сделать это, но с помощью GNU sed вы могли бы сделать, например
$ sed -E 's/(.)\1*/+.*\1/2g' <<< "queen"
q+.*u+.*e+.*n
Теперь проверьте мешанину на каждом сгенерированном образце.
Собираем все воедино:
$ cat script1
#!/bin/bash
wordlist=/usr/share/dict/words
while IFS= read -r word; do
grep -qEx "$(sed -E 's/(.)\1*/+.*\1/2g' <<< "$word")" <<< "$1" && printf '%s\n' "$word"
done < <(grep -x "${1:0:1}.*${1:(-1):1}" "$wordlist")
, затем
$./script1 qwertyuytresdftyuiokn
queen
question
Вот ещё (пробег вbash
)Код python
генерирует регулярное выражение и передает его в grep
. Затем grep
работает с выводом почтенной утилиты look
, которая выполняет двоичный поиск, чтобы получить все слова /usr/share/dict/words
, начинающиеся с q
в примере. Таким образом, grep
имеет значительно сокращенный набор слов для поиска
python3 -c 'import sys
arr = list(sys.argv[1])
print(*arr, sep="*")
' $1 | grep -x -f - <(look ${1:0:1})
В качестве альтернативы, решение look
+ python3
, которое позволяет избежать регулярных выражений
look q |./finder.py "qwertyuytresdftyuiokn"
где finder.py
выглядит следующим образом:
#!/usr/bin/env python3
import sys
from itertools import groupby
seek_word = sys.argv[1]
for word in sys.stdin:
orig_word = word.strip()
word = ''.join(k for k, g in groupby(orig_word))
s_w = iter(seek_word)
i_word = iter(word)
if all(c in s_w for c in i_word) and not next(s_w, None):
print(orig_word)