按唯一列和最新时间​​排序Powershell数组

时间:2017-10-31 17:59:12

标签: arrays powershell sorting unique

我将Syslog消息作为Heartbeat发送,并希望将日志文件显示为已排序的html(按主机和最新收到的心跳)。我的数组看起来像这样:

protocol HasNameProtocol {
    associatedtype FetchableType: NSManagedObject = Self
    static var entityName : String { get }
    var name: String {get}

    static func predicate(name: String) -> NSPredicate
    static func find(name: String, context: NSManagedObjectContext) throws -> [FetchableType]

}

extension HasNameProtocol where FetchableType == Self {    

    static var entityName : String {
        return NSStringFromClass(self).components(separatedBy: ".").last!
    }

   static func predicate(name: String) -> NSPredicate {
        return NSPredicate(format: "name == %@", name)
    }

    static func find(name: String, context: NSManagedObjectContext) throws -> [FetchableType] {
        let request = NSFetchRequest<FetchableType>(entityName: entityName)
        let predicate = predicate(name: name)
        request.predicate = predicate
        return try context.fetch(request)
    }
}

我不想要所有的消息,只是每个主机的最后一个消息。已经尝试过Get-Unique的许多版本; Sort-Object -unique等等但始终失败。

发布的输出由以下产生:

Date                 |   Host       
----                 |   ----       
31.10.2017 16:59:37  |   Host0815      
31.10.2017 16:59:31  |   Host2123      
31.10.2017 16:59:31  |   Host1       
31.10.2017 16:59:31  |   Host0815      
31.10.2017 16:59:25  |   Host0815      
31.10.2017 16:59:25  |   Host2123      
31.10.2017 16:59:25  |   Host1       
31.10.2017 16:59:19  |   Host0815 

$array = $array | Sort-Object Host, Date -Unique | Sort-Object Date -Descending 开关似乎无效。此外,如果我尝试这样排序的独特主机我工作,但我有“随机”日期值,而不是每个最新的。

期望的输出:

-unique

有人可以帮助我,甚至可以告诉我这是否可行?

谢谢!
负载线

3 个答案:

答案 0 :(得分:1)

示例:

$list = @(
  [PSCustomObject] @{
    Date = [DateTime] "10/31/2017 16:59:37"
    Host = "Host0815"
  }
  [PSCustomObject] @{
    Date = [DateTime] "10/31/2017 16:59:31"
    Host = "Host2123"
  }
  [PSCustomObject] @{
    Date = [DateTime] "10/31/2017 16:59:31"
    Host = "Host1"
  }
  [PSCustomObject] @{
    Date = [DateTime] "10/31/2017 16:59:31"
    Host = "Host0815"
  }
  [PSCustomObject] @{
    Date = [DateTime] "10/31/2017 16:59:25"
    Host = "Host0815"
  }
  [PSCustomObject] @{
    Date = [DateTime] "10/31/2017 16:59:25"
    Host = "Host2123"
  }
  [PSCustomObject] @{
    Date = [DateTime] "10/31/2017 16:59:25"
    Host = "Host1"
  }
  [PSCustomObject] @{
    Date = [DateTime] "10/31/2017 16:59:19"
    Host = "Host0815"
  }
)

$list | Sort-Object Host -Unique | Sort-Object Date -Descending

输出:

Date                  Host
----                  ----
10/31/2017 4:59:37 PM Host0815
10/31/2017 4:59:31 PM Host1
10/31/2017 4:59:31 PM Host2123

我创建了示例输入数据($list),其中Date列是实际的[DateTime]对象。我不知道您的数据是否属于这种情况(您可能需要这样做),但我的简短测试会输出您期望的结果。

答案 1 :(得分:0)

首先:感谢您的所有时间!我试图调整你的例子并且它有效,只做了一个“改进”:

$list = @(
[PSCustomObject] @{
Date = [DateTime]::ParseExact("31.10.2017 16:59:37","dd.MM.yyyy HH:mm:ss", $null)
Host = "Host1234"
}...

也有效,非常好!但是现在我尝试将这些更改改编为我的脚本并再次失败:

$data = Get-Content "C:\heartbeat-log.txt" -tail 50

$array.Clear()

        ForEach ($line in $data)
        {
            $string = ($line -split "SPACER,") -split ","

              $array += @(
               [PSCustomObject] @{
                Date = [DateTime]::ParseExact($string[1], "dd.MM.yyyy HH:mm:ss", $null)
                SN = [string]$string[2]
                Host = [string]$string[3]
                Msg = [string]$string[4]
                Status = [string]$string[5]
                CpuCores = [int]$string[6]

              }
              )

        }

这就是我的输入数据的样子(SN因为随机创建的字符串而改变):

SPACER,31.10.2017 21:03:23,MZ58XJ6UBH,Host1,CustomMsg,CustomStatus,2
SPACER,31.10.2017 21:03:23,MZ58XJ6UBH,Host2123,CustomMsg,CustomStatus,2
SPACER,31.10.2017 21:03:29,MZ58XJ6UBH,Host0815,CustomMsg,CustomStatus,2
SPACER,31.10.2017 21:03:29,MZ58XJ6UBH,Host1,CustomMsg,CustomStatus,2
SPACER,31.10.2017 21:03:29,MZ58XJ6UBH,Host2123,CustomMsg,CustomStatus,2
SPACER,31.10.2017 21:03:35,MZ58XJ6UBH,Host0815,CustomMsg,CustomStatus,2
SPACER,31.10.2017 21:03:35,MZ58XJ6UBH,Host1,CustomMsg,CustomStatus,2
SPACER,31.10.2017 21:03:35,MZ58XJ6UBH,Host2123,CustomMsg,CustomStatus,2
SPACER,31.10.2017 21:08:55,PKRTVWLOMJ,Host0815,CustomMsg,CustomStatus,2
SPACER,31.10.2017 21:08:55,PKRTVWLOMJ,Host1,CustomMsg,CustomStatus,2
SPACER,31.10.2017 21:08:55,PKRTVWLOMJ,Host2123,CustomMsg,CustomStatus,2
SPACER,31.10.2017 21:09:01,PKRTVWLOMJ,Host0815,CustomMsg,CustomStatus,2
SPACER,31.10.2017 21:09:01,PKRTVWLOMJ,Host1,CustomMsg,CustomStatus,2
SPACER,31.10.2017 21:09:01,PKRTVWLOMJ,Host2123,CustomMsg,CustomStatus,2

使用您的排序示例输出:

$array | Sort-Object Host -Unique | Sort-Object Date -Descending | ft

Date                    SN            Host        Msg        Status        CpuCores
----                    --            ----        ---        ------        --------
31.10.2017 21:03:23     MZ58XJ6UBH    Host1       CustomMsg  CustomStatus  2
31.10.2017 19:54:06     XM6YCR5ED2    Host2123    CustomMsg  CustomStatus  2
31.10.2017 19:50:46     QJKWLD7901    Host0815    CustomMsg  CustomStatus  2

期望:

Date                    SN            Host        Msg        Status        CpuCores
----                    --            ----        ---        ------        --------
31.10.2017 21:09:01     PKRTVWLOMJ    Host1       CustomMsg  CustomStatus  2
31.10.2017 21:09:01     PKRTVWLOMJ    Host2123    CustomMsg  CustomStatus  2
31.10.2017 21:09:01     PKRTVWLOMJ    Host0815    CustomMsg  CustomStatus  2

为什么“相同”数组在手动填充但不在我的版本中时有效?

(希望这次我的帖子格式正确;))

非常感谢!

答案 2 :(得分:0)

PowerShell的独特之处并不是为了解决这种复杂性。您可以先按主机分组,然后再按主机分类和选择:

$array | group Host | % {$_ | select -ExpandProperty group | sort Date -Descending | select -First 1}


Date                Host    
----                ----
31.10.2017 16:59:37 Host0815    
31.10.2017 16:59:31 Host2123    
31.10.2017 16:59:31 Host1