Powershell - 从大型文本文件创建哈希表并进行搜索
Powershell - creating hashtables from large text files and searching
我正在使用一个散列table,它是使用以 CSV 格式存储的 350 万个 IP 地址列表构建的,我正在尝试使用通配符搜索此 table .
CSV 是 MaxMind 的 IP 列表,我使用以下代码将其转换为 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 及其对应的 City/Country 代码。
这很好用,并在两分钟多一点的时间内构建了 table,但我现在面临的问题是在这个哈希 table 中搜索通配符条目。
如果我搜索完整的 CIDR,搜索会在几毫秒内完成
$mainIPHhash.item("1.0.0.0/24")
Measure command reports - TotalSeconds : 0.0001542
但是如果我需要做一个通配符搜索,它必须通过散列循环table寻找我喜欢的值,这需要很长时间!
$testingIP = "1.0.*"
$mainIPHhash.GetEnumerator() | Where-Object { $_.key -like $testingIP }
Measure command reports - TotalSeconds : 33.3016279
是否有更好的方法在 Hashtable 中搜索通配符条目?
干杯
编辑:
使用正则表达式搜索,我可以将其缩短到 19 秒。但还是慢得可怜
$findsStr = "^$(($testingIP2).split('.')[0])" +"\."+ "$(($testingIP2).split('.')[1])" +"\."
$mainIPHhash.GetEnumerator() | foreach {if($_.Key -match $findsStr){#Dostuff }}
以上获取 IP 地址的前两个八位字节,并使用正则表达式在哈希中找到它们table。
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
您可以获取 IP 列表并对列表执行 -like
或 -match
。两者都应该比 Where-Object
子句
快
$mainIPhash.Values -like '1.0.*'
$mainIPhash.Values -match '^1\.0\.'
其他解决方案可能是,使用组对象:
$contentcsv=import-csv "C:\temp\iptest.csv" -Header Name, geoname_id, registered_country_geoname_id |Group Name
$contentcsv | where Name -like '1.0.*'
我正在使用一个散列table,它是使用以 CSV 格式存储的 350 万个 IP 地址列表构建的,我正在尝试使用通配符搜索此 table .
CSV 是 MaxMind 的 IP 列表,我使用以下代码将其转换为 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 及其对应的 City/Country 代码。 这很好用,并在两分钟多一点的时间内构建了 table,但我现在面临的问题是在这个哈希 table 中搜索通配符条目。
如果我搜索完整的 CIDR,搜索会在几毫秒内完成
$mainIPHhash.item("1.0.0.0/24")
Measure command reports - TotalSeconds : 0.0001542
但是如果我需要做一个通配符搜索,它必须通过散列循环table寻找我喜欢的值,这需要很长时间!
$testingIP = "1.0.*"
$mainIPHhash.GetEnumerator() | Where-Object { $_.key -like $testingIP }
Measure command reports - TotalSeconds : 33.3016279
是否有更好的方法在 Hashtable 中搜索通配符条目?
干杯
编辑:
使用正则表达式搜索,我可以将其缩短到 19 秒。但还是慢得可怜
$findsStr = "^$(($testingIP2).split('.')[0])" +"\."+ "$(($testingIP2).split('.')[1])" +"\."
$mainIPHhash.GetEnumerator() | foreach {if($_.Key -match $findsStr){#Dostuff }}
以上获取 IP 地址的前两个八位字节,并使用正则表达式在哈希中找到它们table。
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
您可以获取 IP 列表并对列表执行 -like
或 -match
。两者都应该比 Where-Object
子句
$mainIPhash.Values -like '1.0.*'
$mainIPhash.Values -match '^1\.0\.'
其他解决方案可能是,使用组对象:
$contentcsv=import-csv "C:\temp\iptest.csv" -Header Name, geoname_id, registered_country_geoname_id |Group Name
$contentcsv | where Name -like '1.0.*'