Powershell — создание хеш-таблиц из больших текстовых файлов и поиск

Я работаю с хеш-таблицей, которую я создал, используя список из 3,5 миллионов IP-адресов, хранящихся в формате CSV, и я пытаюсь выполнить поиск в этой таблице с помощью подстановочных знаков.

CSV — это список IP-адресов MaxMind, который я конвертирую в Hashtable, используя следующий код.

[System.IO.File]::ReadLines("C:\temp\iptest.csv") | ForEach-Object { $data= $_.split(','); $ht = @{"geoname_id" = "$($data[1])";"registered_country_geoname_id" = "$($data[2])"}
$name = $($data[0])
$mainIPHhash.add($name, $ht)}

Код просто извлекает CIDR и соответствующий код города/страны. Это работает хорошо и создает таблицу чуть более чем за две минуты, но проблема, с которой я сейчас сталкиваюсь, заключается в поиске в этой хэш-таблице записей с подстановочными знаками.

Если я ищу полный CIDR, поиск происходит за миллисекунды.

$mainIPHhash.item("1.0.0.0/24")

Measure command reports - TotalSeconds : 0.0001542

Но если мне нужно выполнить поиск по подстановочным знакам, он должен пройтись по хеш-таблице в поисках моих похожих значений, что занимает много времени!

$testingIP = "1.0.*"
$mainIPHhash.GetEnumerator() | Where-Object { $_.key -like $testingIP }

Measure command reports - TotalSeconds : 33.3016279

Есть ли лучший способ поиска записей с подстановочными знаками в Hashtables?

Ваше здоровье

Редактировать:

Используя поиск по регулярному выражению, я могу сократить его до 19 секунд. Но все равно ужасно медленно


$findsStr = "^$(($testingIP2).split('.')[0])" +"\."+ "$(($testingIP2).split('.')[1])" +"\."

$mainIPHhash.GetEnumerator() | foreach {if ($_.Key -match $findsStr){#Dostuff }}

В приведенном выше примере берутся первые два октета IP-адреса и используется регулярное выражение для их поиска в хеш-таблице.


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 19
Milliseconds      : 733
Ticks             : 197339339
TotalDays         : 0.000228402012731481
TotalHours        : 0.00548164830555556
TotalMinutes      : 0.328898898333333
TotalSeconds      : 19.7339339
TotalMilliseconds : 19733.9339
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
133
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете взять список IP-адресов и сделать либо -like, либо -match для списка. Либо должно быть быстрее, чем предложение Where-Object

$mainIPhash.Values -like '1.0.*'

$mainIPhash.Values -match '^1\.0\.'

Вы, сэр, легенда. Это сработало отлично. Спасибо.

WhistleButton 21.12.2020 03:12

Что было быстрее? У меня действительно большой список со многими дубликатами.

Doug Maurer 21.12.2020 03:13

Они хорошенькие на уровне! Вывод из команды измерения для первого - TotalMilliseconds: 0,1165. Второй - TotalMilliseconds: 0,1237

WhistleButton 21.12.2020 03:22

Другим решением может быть использование group-object :

$contentcsv=import-csv "C:\temp\iptest.csv" -Header Name, geoname_id, registered_country_geoname_id |Group Name
$contentcsv | where Name -like '1.0.*'

Спасибо! Единственная проблема заключается в том, что import-csv с таким большим файлом потребляет огромное количество ресурсов.

WhistleButton 21.12.2020 06:33

а ок, понял :)

Esperento57 21.12.2020 12:06

Другие вопросы по теме