如何对包含数组的哈希图进行排序
How to sort a hashmap containing arrays
我得到了一个包含日期和 IP 的日志数据。
现在我想知道哪一天是哪个IP。
我使用哈希图来使用键<=>值对。
但不幸的是有重复的:
Day1<=>IP1, Day1<=>IP2, Day1<=>IP3, Day2<=>IP1, Day3<=>IP2, Day3<=>IP1
我曾经使用数组作为键<=>值对,所以我仍然可以使用
重复为 hashentries。我可以将哈希表的输出分组
这样它就会像这样显示:
date<=>IP1, IP2, IP3
date<=>IP1, IP2, IP3
?
我在考虑group-object
方法。
/编辑:
示例输入可以是:
26.12.2014 1.1.1.1
28.12.2014 2.2.2.2
29.12.2014 1.1.1.1
29.12.2014 2.2.2.2
30.12.2014 2.2.2.2
30.12.2014 3.3.3.3
30.12.2014 3.3.3.3
30.12.2014 3.3.3.3
30.12.2014 4.4.4.4
30.12.2014 1.1.1.1
30.12.2014 2.2.2.2
我正在尝试获取每天的所有访问权限。所有条目都是数组
因为您的键不能有多个值。
所需的输出应该是这样的:
26.12.2014: 1
2014 年 12 月 28 日:1
2014 年 12 月 29 日:2
2014 年 12 月 30 日:7
数字显示每天的访问量。
/编辑 2:
示例代码如下:
$items = Get-ChildItem "$PSScriptRoot\*file*"
foreach ($item in $items)
{
$item_name = $item.Name
$content = [System.IO.File]::ReadAllLines("$PSScriptRoot$item_name")
$hash = @{}
foreach($line in $content)
{
$hash.Add(@(((filter_date($line)).split(" ")[1])), @(((filter_date($line)).split(" ")[0])))
}
}
filter_date 是一个子程序,它切断了每行的 IP 和日期。
有什么帮助吗? (针对新要求和示例数据进行了编辑)
$data =
(@'
26.12.2014 1.1.1.1
28.12.2014 2.2.2.2
29.12.2014 1.1.1.1
29.12.2014 2.2.2.2
30.12.2014 2.2.2.2
30.12.2014 3.3.3.3
30.12.2014 3.3.3.3
30.12.2014 3.3.3.3
30.12.2014 4.4.4.4
30.12.2014 1.1.1.1
30.12.2014 2.2.2.2
'@).split("`n")
$ht = [ordered]@{}
$data |
foreach {$ht[$_.split()[0]]++}
[PSCustomObject]$ht | format-list
26.12.2014 : 1
28.12.2014 : 1
29.12.2014 : 2
30.12.2014 : 7
您似乎只想要按日期排序的列表中每天的条目数。如果是这样,我建议为整个脚本创建一个哈希表,以日期为键,一个简单的 int
-counter 作为值。如果您不需要保留 IP,那么存储它们就是浪费时间和资源。尝试:
#Create hashtable to store date = access per day.
$hash = @{}
#Get files
$items = Get-ChildItem "$PSScriptRoot\*file*"
foreach($item in $items) {
#The FullName-property of a FileInfo-object (result from Get-ChildItem) contains full filepath.
$content = [System.IO.File]::ReadAllLines($item.FullName)
foreach($line in $content) {
$data = filter_date($line).Split(" ")#Expecting 2 parts: [0] = Date, [1] = IP
if($hash.ContainsKey($data[0])) {
#Date previously registered, count = count + 1
$hash[$data[0]] += 1
} else {
#First instance of date, count = 1
$hash[$data[0]] = 1
}
}
}
#Loop through hash
$hash.GetEnumerator() |
#Sort by date
Sort-Object { [datetime]::ParseExact($_.Key, 'dd.MM.yyyy', $null) } |
#Format result
ForEach-Object { "$($_.Key): $($_.Value)" }
26.12.2014: 1
28.12.2014: 1
29.12.2014: 2
30.12.2014: 7
我得到了一个包含日期和 IP 的日志数据。
现在我想知道哪一天是哪个IP。
我使用哈希图来使用键<=>值对。
但不幸的是有重复的:
Day1<=>IP1, Day1<=>IP2, Day1<=>IP3, Day2<=>IP1, Day3<=>IP2, Day3<=>IP1
我曾经使用数组作为键<=>值对,所以我仍然可以使用
重复为 hashentries。我可以将哈希表的输出分组
这样它就会像这样显示:
date<=>IP1, IP2, IP3
date<=>IP1, IP2, IP3
?
我在考虑group-object
方法。
/编辑:
示例输入可以是:
26.12.2014 1.1.1.1
28.12.2014 2.2.2.2
29.12.2014 1.1.1.1
29.12.2014 2.2.2.2
30.12.2014 2.2.2.2
30.12.2014 3.3.3.3
30.12.2014 3.3.3.3
30.12.2014 3.3.3.3
30.12.2014 4.4.4.4
30.12.2014 1.1.1.1
30.12.2014 2.2.2.2
我正在尝试获取每天的所有访问权限。所有条目都是数组
因为您的键不能有多个值。
所需的输出应该是这样的:
26.12.2014: 1
2014 年 12 月 28 日:1
2014 年 12 月 29 日:2
2014 年 12 月 30 日:7
数字显示每天的访问量。
/编辑 2:
示例代码如下:
$items = Get-ChildItem "$PSScriptRoot\*file*"
foreach ($item in $items)
{
$item_name = $item.Name
$content = [System.IO.File]::ReadAllLines("$PSScriptRoot$item_name")
$hash = @{}
foreach($line in $content)
{
$hash.Add(@(((filter_date($line)).split(" ")[1])), @(((filter_date($line)).split(" ")[0])))
}
}
filter_date 是一个子程序,它切断了每行的 IP 和日期。
有什么帮助吗? (针对新要求和示例数据进行了编辑)
$data =
(@'
26.12.2014 1.1.1.1
28.12.2014 2.2.2.2
29.12.2014 1.1.1.1
29.12.2014 2.2.2.2
30.12.2014 2.2.2.2
30.12.2014 3.3.3.3
30.12.2014 3.3.3.3
30.12.2014 3.3.3.3
30.12.2014 4.4.4.4
30.12.2014 1.1.1.1
30.12.2014 2.2.2.2
'@).split("`n")
$ht = [ordered]@{}
$data |
foreach {$ht[$_.split()[0]]++}
[PSCustomObject]$ht | format-list
26.12.2014 : 1
28.12.2014 : 1
29.12.2014 : 2
30.12.2014 : 7
您似乎只想要按日期排序的列表中每天的条目数。如果是这样,我建议为整个脚本创建一个哈希表,以日期为键,一个简单的 int
-counter 作为值。如果您不需要保留 IP,那么存储它们就是浪费时间和资源。尝试:
#Create hashtable to store date = access per day.
$hash = @{}
#Get files
$items = Get-ChildItem "$PSScriptRoot\*file*"
foreach($item in $items) {
#The FullName-property of a FileInfo-object (result from Get-ChildItem) contains full filepath.
$content = [System.IO.File]::ReadAllLines($item.FullName)
foreach($line in $content) {
$data = filter_date($line).Split(" ")#Expecting 2 parts: [0] = Date, [1] = IP
if($hash.ContainsKey($data[0])) {
#Date previously registered, count = count + 1
$hash[$data[0]] += 1
} else {
#First instance of date, count = 1
$hash[$data[0]] = 1
}
}
}
#Loop through hash
$hash.GetEnumerator() |
#Sort by date
Sort-Object { [datetime]::ParseExact($_.Key, 'dd.MM.yyyy', $null) } |
#Format result
ForEach-Object { "$($_.Key): $($_.Value)" }
26.12.2014: 1
28.12.2014: 1
29.12.2014: 2
30.12.2014: 7