如何在 Powershell 中使用数组搜索集合
How to search a collection with an array in Powershell
我有一组来自 Outlook 的 MailItems
。我想根据数组中包含的搜索词列表搜索每个邮件项目和 return Subject
和 Category
- 在名为 $searchArray
.[= 的示例中21=]
例如:
$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>
}
我想 return Subject
,然后是名为 Category
的列,该列将查看 $msg.SenderEmailAddress
以及 [= 中是否有任何 searchTerms 14=] 包含在地址中,return 包含该搜索词的类别。
例如,如果 SenderEmailAddress
值之一是 "searchTerm2@somewhere.com",则 return 类别 1 作为 Category
。
我会翻转这个数组并从中创建一个哈希表。然后使用第一个匹配的搜索词作为类别的查找键:
$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)]
}
}
还是需要像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 "|"
}
}
现在搜索词会自动转义并加入搜索模式。
使用开关:
$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
}
我有一组来自 Outlook 的 MailItems
。我想根据数组中包含的搜索词列表搜索每个邮件项目和 return Subject
和 Category
- 在名为 $searchArray
.[= 的示例中21=]
例如:
$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>
}
我想 return Subject
,然后是名为 Category
的列,该列将查看 $msg.SenderEmailAddress
以及 [= 中是否有任何 searchTerms 14=] 包含在地址中,return 包含该搜索词的类别。
例如,如果 SenderEmailAddress
值之一是 "searchTerm2@somewhere.com",则 return 类别 1 作为 Category
。
我会翻转这个数组并从中创建一个哈希表。然后使用第一个匹配的搜索词作为类别的查找键:
$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)]
}
}
还是需要像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 "|"
}
}
现在搜索词会自动转义并加入搜索模式。
使用开关:
$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
}