如何在Powershell中搜索带有数组的集合

时间:2016-04-08 09:33:19

标签: arrays powershell powershell-v3.0

我有一个来自Outlook的MailItems数组。我想搜索每个邮件项,并根据数组中包含的搜索字词列表返回SubjectCategory - 在名为$searchArray的示例中。

例如:

$mailbox = "my.mailbox@example.com"

$outlook = New-Object -com Outlook.Application
$ns = $outlook.GetNamespace("MAPI")
$inbox = $ns.Folders.Item($mailbox).Folders.Item("Inbox")
$searchItems = $inbox.Folders.Item("MySubFolder").Folders.Item("MyNestedSubFolder").Items

$searchArray = (
    "Category1", ("searchTerm1","searchTerm2","searchTerm3"),
    "Category2", ("searchTerm4","searchTerm5"),
    "Category3", ("searchTerm6")
)

foreach ($msg in $searchItems) {
    $msg | select Subject, # <Category where email address contains one of the search terms>
}

我想返回Subject,然后返回名为Category的列,该列将查看$msg.SenderEmailAddress以及$searchArray中是否包含SenderEmailAddress中的任何searchTerms地址,返回其中包含该搜索词的类别。

例如,如果其中一个Category值为“searchTerm2@somewhere.com”,则将Category1作为Unknown entity: com.se.automation.db.client.mapping.DocumentWRONGMODDATESTATUS返回。

3 个答案:

答案 0 :(得分:2)

我会将这个数组翻转过来并从中创建一个哈希表。然后使用第一个匹配的搜索词作为类别的查找键:

$searchArray = (
    "Category1", ("searchTerm1","searchTerm2","searchTerm3"),
    "Category2", ("searchTerm4","searchTerm5"),
    "Category3", ("searchTerm6")
)

# Create hashtable
$searchTable = @{}

# Populate hash table with values from array
for($i=0;$i-lt$searchArray.Count;$i+=2){ 
    foreach($term in $searchArray[$i+1])
    {
        $searchTable[$term] = $searchArray[$i]
    }
}

# Select Category based on first matching search term
$msg |Select-Object Subject,@{Name="Category";Expression={
        $sender = $_.SenderEmailAddress
        $searchTable[$($searchTable.Keys |Where-Object{$sender -like "*$_*"} |Select -First 1)]
    }
}

答案 1 :(得分:1)

仍然需要像Mathias那样使用计算表达式(这真的是简单的方法)。但是我想展示一种方法,其中有$searchArray的自定义对象数组。如果你要从头开始定制它,它看起来就像这样。我还将这些术语转换为正则表达式模式匹配,因为您说它们是唯一的。唯一需要注意的是,您需要确保搜索字词中没有正则表达式元字符。

$searchArray = (
    [pscustomobject]@{
        Category = "1"
        Pattern = "searchTerm1|searchTerm2|searchTerm3"
    },  
    [pscustomobject]@{
        Category = "2"
        Pattern = "searchTerm4|searchTerm5"
    },
    [pscustomobject]@{
        Category = "3"
        Pattern = "searchTerm6"}
)

foreach ($msg in $searchItems) {
    $msg | select Subject, @{
        Name="Category";
        Expression={$searchArray | Where-Object{$msg.SenderEmailAddress -match $_.pattern } | Select-Object -ExpandProperty Category}
    } 
}

解决方案依赖于类型加速器[pscustomobject]中的PowerShell 3.0。如果需要,可以轻松将其恢复到2.0。

使用2.0展示类似的结构,并将数组自动转换为适用于我的代码的数组。

$newSearchArray = for($categoryIndex=0;$categoryIndex-lt$searchArray.Count;$categoryIndex+=2){ 
    New-Object -TypeName pscustomobject -Property @{
        Category = $searchArray[$categoryIndex]
        Pattern = ($searchArray[$categoryIndex+1] | ForEach-Object{[regex]::Escape($_)}) -join "|"
    }
}

现在搜索字词会自动转义并加入搜索模式。

答案 2 :(得分:0)

使用开关:

$mailbox = "my.mailbox@example.com"

$outlook = New-Object -com Outlook.Application
$ns = $outlook.GetNamespace("MAPI")
$inbox = $ns.Folders.Item($mailbox).Folders.Item("Inbox")
$searchItems = $inbox.Folders.Item("MySubFolder").Folders.Item("MyNestedSubFolder").Items

foreach ($msg in $searchItems) {
    $object = $msg | select Subject,Category # <Category where email address contains one of the search terms>
    Switch -Regex ($msg.SenderEmailAddress)
    {
      'searchTerm1|searchTerm2|searchTerm3' { $object.Catetory = 'Category1' ; break }
      'searchTerm4|searchTerm5'             { $object.Catetory = 'Category2' ; break }
      'searchTerm6'                         { $object.Catetory = 'Category3' ; break }
    }
    $object
}