【问题标题】:PowerShell - Removing Items from ArrayPowerShell - 从数组中删除项目
【发布时间】:2021-11-03 12:02:31
【问题描述】:

我正在尝试从与特殊关键字匹配的数组中删除项目。我的数组看起来像这样:

$Printers =@('Printer Phone', 'Printer Building1', 'Printer XML', 'Printer Station', ...) 

我想删除与某些字符串的某些部分匹配的所有条目,例如过滤掉其值中包含“Phone”或“XML”的每个项目。我想过这样的事情,但我不确定我是否走在正确的轨道上:

$contains = @('Phone', 'XML')
$Printers -Filter * | Where-Object { $contains -contains $_.name }

有没有简单的方法来实现这一点?

【问题讨论】:

  • $Printers |Select-String -NotMatch $Contains

标签: arrays powershell


【解决方案1】:

这是一种方法。

> $contains = @('Phone', 'XML')
> $Printers = @('Printer Phone','Printer Building1','Printer XML', 'Printer Station')
> $Printers | Where-Object { $_ -Match ($contains -Join "|") }
Printer Phone
Printer XML
> $Printers | Where-Object { $_ -notMatch ($contains -Join "|") }
Printer Building1
Printer Station

【讨论】:

  • 这是一个优雅的解决方案,但如果您稍微解释一下并提到可能需要将[regex]::Escape() 应用于搜索词(在示例输入中不是必需的),它会有所帮助。此外,如果您允许读者按原样复制和粘贴解决方案以便在单个操作中尝试它,而不必删除 > 前缀或复制和粘贴每行的相关部分,这将有所帮助个人。
【解决方案2】:

三句话

  • 您不需要@() 来创建数组。 逗号 是数组的组成部分,@() 在这里是多余的。
  • PowerShell -contains 运算符检查字符串是否包含子字符串。它检查数组是否包含值。
    使用the .NET .Contains() method 可用于子字符串检查,但请注意,它区分大小写。如果您需要不区分大小写的比较,请将您的字符串小写(比doing it "by the book" 好且容易)。
  • 您在{} 脚​​本块中生成并且分配给变量的任何值都将成为该脚本块输出的一部分。这就是下面的 Where-Object 块的工作原理。

代码:

$Printers = 'Printer Phone','Printer Building1','Printer XML', 'Printer Station' 
$contains = 'Phone','XML'

$Printers | Where-Object { 
    $printer = $_
    $contains | Where-Object {  $printer.Contains($_) }
}

Where-Object 将非空输出视为$true。因此,将$contains 过滤为某事(或什么都没有)将决定$Printers 值是否成功。以上打印件

Printer Phone
Printer XML

您可以使用-match,但您必须开始担心正则表达式正确转义您的$contains 值以避免运行时错误。

【讨论】:

    【解决方案3】:

    你可以有一个带有选择字符串的模式数组。但是 select-string 的输出是一个 matchinfo 对象(除非它被转换为字符串),并且 line 属性检查了原始字符串。

    $patterns = echo Phone XML
    $printers = 'Printer Phone', 'Printer Building1', 'Printer XML',
      'Printer Station'
    $printers | select-string $patterns | % line
    
    Printer Phone
    Printer XML
    

    不幸的是,-contains 是一个常见的混淆点。

    'printer station' -contains 'station'
    
    False
    
    
    -split 'printer station' -contains 'station'
    
    True
    

    【讨论】:

    • 很好,虽然在这种情况下添加-SimpleMatch 更安全,用于literal 子字符串搜索。在 PowerShell (Core) 7+ 中,-Raw 现在可用于将匹配行直接输出为字符串;例如$printers | select-string -Raw -SimpleMatch $patterns
    猜你喜欢
    • 2014-09-05
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 2021-10-19
    • 2021-10-03
    • 2014-09-21
    • 2013-06-08
    相关资源
    最近更新 更多