【发布时间】:2021-12-13 00:04:41
【问题描述】:
有没有一种非 for 循环的方法可以从 arrayList 中删除一些项目?
$remotesumerrors = $remoteFiles | Select-String -Pattern '^[a-f0-9]{32}( )' -NotMatch
我想从 $remoteFiles var 中删除上述输出。有什么管道方法可以删除它们吗?
【问题讨论】:
标签: arrays powershell
有没有一种非 for 循环的方法可以从 arrayList 中删除一些项目?
$remotesumerrors = $remoteFiles | Select-String -Pattern '^[a-f0-9]{32}( )' -NotMatch
我想从 $remoteFiles var 中删除上述输出。有什么管道方法可以删除它们吗?
【问题讨论】:
标签: arrays powershell
假设以下所有:
$remotesumerrors 中捕获的结果$remoteFiles 是 System.IO.FileInfo 实例的集合,例如 Get-ChildItem 的输出$remoteFiles,您可以按如下方式使用.Where() array method(这优于基于Where-Object cmdlet 的基于管道的解决方案):
# Get the distinct set of the full paths of the files of origin
# from the Select-String results stored in $remotesumerrors
# as a hash set, which allows efficient lookup.
$errorFilePaths =
[System.Collections.Generic.HashSet[string]] $remotesumerrors.Path
# Get those file-info objects from $remoteFiles
# whose paths aren't in the list of the paths obtained above.
$remoteFiles = $remoteFiles.Where({ -not $errorFilePaths.Contains($_.FullName) })
顺便说一句:
[System.Collections.Generic.HashSet[T]] 是获取一组不同值(删除重复项)的一种快速便捷的方法,但请注意,生成的哈希集的元素总是无序,并且字符串,默认情况下查找区分大小写-敏感 - 请参阅this answer 了解更多信息。【讨论】:
使用Where-Object cmdlet 过滤列表:
$remoteFiles = $remoteFiles |Where-Object { $_ |Select-String -Pattern '^[a-f0-9]{32}( )' -NotMatch }
【讨论】:
-Quiet 以优化Select-String 调用。结果将是一个 array (或单个文件信息对象)也毫无价值-尽管@Tony 在引用“arrayList”而不是System.Collections.ArrayList 实例时可能实际上是指一个数组。
Where-Object { -not ($_ |Select-String -Quiet -NotMatch -Pattern '^[a-f0-9]{32}( )') }
如果它确实是一个 [collections.arraylist],您可以按值删除一个元素。还有.RemoveAt(),按数组索引删除。
[System.Collections.ArrayList]$array = 'a','b','c','d','e'
$array.remove
OverloadDefinitions
-------------------
void Remove(System.Object obj)
void IList.Remove(System.Object value)
$array.remove('c')
$array
a
b
d
e
【讨论】:
假设 $remoteFiles 是 System.IO.FileInfo 类型的文件对象。我还假设您要根据文件名进行过滤。
$remotesumerrors = $remoteFiles.name | Select-String -Pattern '^[a-f0-9]{32}' -NotMatch
试图用“( )”做什么或者你想要做什么查询。
编辑:根据评论更正答案
【讨论】: