【问题标题】:Powershell Remove objects from an array listPowershell 从数组列表中删除对象
【发布时间】:2021-12-13 00:04:41
【问题描述】:

有没有一种非 for 循环的方法可以从 arrayList 中删除一些项目?

$remotesumerrors = $remoteFiles | Select-String  -Pattern '^[a-f0-9]{32}(  )' -NotMatch

我想从 $remoteFiles var 中删除上述输出。有什么管道方法可以删除它们吗?

【问题讨论】:

    标签: arrays powershell


    【解决方案1】:

    假设以下所有:

    • 您确实需要单独在$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 了解更多信息。

    【讨论】:

      【解决方案2】:

      使用Where-Object cmdlet 过滤列表:

      $remoteFiles = $remoteFiles |Where-Object { $_ |Select-String -Pattern '^[a-f0-9]{32}(  )' -NotMatch }
      

      【讨论】:

      • 嗯,他们似乎都还在 remoteFiles var ...
      • 很好,不过我建议添加-Quiet 以优化Select-String 调用。结果将是一个 array (或单个文件信息对象)也毫无价值-尽管@Tony 在引用“arrayList”而不是System.Collections.ArrayList 实例时可能实际上是指一个数组。
      • 哦,我该如何使用 -ne 做到这一点?
      • 这可能只是一个错字,但请注意,如果您像使用原始代码示例那样实现过滤器,即 ($remotesumerrors = $remoteFiles | etc.} $remoteFiles 将保持不变,因为新的过滤数组列表被保存到“$remotesumerrors”。你必须使用与上面的答案中的 mathias 相同的变量名。
      • @Tony: Where-Object { -not ($_ |Select-String -Quiet -NotMatch -Pattern '^[a-f0-9]{32}( )') }
      【解决方案3】:

      如果它确实是一个 [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
      

      【讨论】:

        【解决方案4】:

        假设 $remoteFiles 是 System.IO.FileInfo 类型的文件对象。我还假设您要根据文件名进行过滤。

        $remotesumerrors = $remoteFiles.name | Select-String  -Pattern '^[a-f0-9]{32}' -NotMatch
        

        试图用“( )”做什么或者你想要做什么查询。

        编辑:根据评论更正答案

        【讨论】:

        • [a-f0-9] 完全有效。 [a-f][0-9] 也是如此。但他们正在做不同的事情。第一个仅匹配单个字符,可以是任何字母 a - f 或任何 num 0-9,您的版本匹配两个相邻字符,其中第一个是 a-f,第二个是 num 0-9
        • @diopside 我会告诉你,但什么是“()”。
        • 这是个好问题。我不确定在这种情况下。我在正则表达式拆分操作中使用了类似的东西来根据字符串中是否存在空格来移动/填充结果列表,但不确定它在这里做什么。我只使用过一次选择字符串 cmd,所以我需要阅读它
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-12-04
        • 1970-01-01
        • 2011-11-05
        • 2021-08-03
        • 1970-01-01
        • 2020-04-17
        相关资源
        最近更新 更多