Дада, ты не ослышался, начиная с bash 4.0 можно и такое провернуть. Дай нам палку и гвоздь, а мы сделаем из этого кофеварку, мыж с тобой настоящие инженеры-программисты, фак ее!
Летсгоу! Есть у меня огромный txt файл со словами, отсортированный по алфавиту. Нет, не словарь для брутфорса 🍸
Если на него натравить
sed, то скорость извлечения нужного слова из файла — ну совсем никакая, сидишь как баран ждешь, пока этот сыщик Коломбо, что-то откроет-отроет. Но в век высокий технологий, скорость как-никак в приоритете. SED – это потоковый редактор текста (от stream editor), c помощью которого можно выполнять с файлами множество операций вроде поиска и замены, вставки или удаления. При этом чаще всего он используется именно для поиска и замены.
Давай разгонять этого ленивца «Блиц, скорость без границ»
Каков план:
1. Отсортировать содержимое txt файла по алфавиту
2. Проиндексировать данные
Так как файл у меня содержит слова (не цифры и т.п.), то индексами я сделаю диапазоны строк начинающихся на определенную букву.
sort -o data.txt data.txtЭта команда отсортирует содержимое файла data.txt по алфавиту и перезапишет его в нужном мне формате.
Пишем код
Проверяем первый аргумент переданный в скрипт. Если передать что-то кроме букв, то экзитим:
[[ $1 =~ ^[a-z]+$ ]] || exitБерем первую букву из первого аргумента и присваиваем её переменной.
INDEX=${1:0:1}
Инициализируем переменную SEARCH значением первого аргумента, чтобы нам было удобнее в будущем. Это будет искомым словом по нашей базе.SEARCH=$1Далее объявляем переменную DATA. В которой будет указываться путь до нашего файла. Который мы заранее отсортировали по алфавиту.
DATA=data.txtОбъявляем и инициализируем hash ассоциативный массив. Будет работать начиная с bash 4.0, это важно.
declare -A HASH=(['a']=1,1001 ['b']=1002,2002 ['c']=2003,3003
)
Тут я сократил, ниже скрипт полностью.Здесь можешь ручками заполнить этот хэш, а можешь еще один скрипт написать, чтобы автоматом заполнился. Но проще ручками, чтобы не
Что
Короче выявляем короткие диапазоны, по которым будем осуществлять дальнейший поиск. Зачем тебе лопатить весь файл, если можно пройтись по нужному диапазону.
Далее отдаём утилите «sed» диапазон строк и само искомое слово. В данном примере я делаю два вызова через пайп (pipe), но можно извернуться и обойтись одним.
sed -n "${HASH[$INDEX]}p" | sed -n "/^${SEARCH}$/{p;q}"
Весь скрипт будет выглядеть так:#!/bin/shНичего сложного, а самое главное мы используем инструменты, которые поставляются из коробки с Linux. Ну и конечно же в несколько тысяч раз повысили и оптимизировали скорость чтения данных из огромного текстового файла.
[[ $1 =~ ^[a-z]+$ ]] || exit
INDEX=${1:0:1}
SEARCH=$1
DATA=path
declare -A HASH=(
['a']=1,1001 ['b']=1002,2002 ['c']=2003,3003
['d']=3004,4004 ['e']=4005,5005 ['f']=5006,6006
['g']=6007,7007 ['h']=7008,8008 ['i']=8009,9009
['j']=9010,10010 ['k']=10011,11011 ['l']=11012,12012
['m']=12013,13013 ['n']=13014,14014 ['o']=14015,15015
['p']=15016,16016 ['q']=16017,17017 ['r']=17018,18018
['s']=18019,19019 ['t']=19020,20020 ['u']=20021,21021
['v']=21022,22022 ['w']=22023,23023 ['x']=23024,24024
['y']=24025,25025 ['z']=25026,26026 )
sed -n "${HASH[$INDEX]}p" "$DATA" | sed -n "/^${SEARCH}$/{p;q}"
Не нужно стрелять из пушки по воробьям используя какие-то мастодонтные решения. С помощью гвоздя и палки, можно творить настоящие чудеса.
Надеюсь коллеги вам было интересно, продолжим завтра!
Show must go on ☺️
tags: #linux #bash
—
🟢 Подпишись: @bashdays