Powershell ArrayList删除具有特殊字符的项目

时间:2018-07-19 15:23:30

标签: powershell arraylist special-characters

我这样做

[System.Collections.ArrayList]$packageList = (Get-ChildItem "\\path-to-files" -Filter *.zip )
Write-Host $packageList
$packageList.Remove("ABC_Export-Cars.zip")
Write-Host $packageList

Remove不适用于这种项目,但它在数组中。用一个简单的数组例如它包含“ A”,“ B”,“ C”。需要对“ _”或“-”字符进行特殊处理吗?

3 个答案:

答案 0 :(得分:4)

问题是您的ArrayList包含Get-ChildItem返回的FileInfo对象的集合。因此,这些项目均与您要删除的字符串不匹配。显然,当您使用字符串(a,b,c)的集合时,可以匹配要删除的字符串。

您可能只需要ArrayList中的文件名,在这种情况下,请执行以下操作:

[System.Collections.ArrayList]$packageList = (Get-ChildItem "\\path-to-files" -Filter *.zip).name

然后.Remove操作应适用于指定的文件名。

答案 1 :(得分:3)

Mark Wragg's helpful answer很好地解释了您的尝试存在的问题,并提供了仅基于名称的有效替代方法。

如果您确实想收集[System.IO.FileInfo]Get-ChildItem中输出的$packageList实例(而不只是它们的.Name属性值),则您的.Remove()的方法不能起作用,因为您必须按顺序传递已经是数组列表一部分的 [System.IO.FileInfo]实例成功删除它。

原因是.Remove()方法使用引用相等查找.NET reference types实例的列表元素(唯一的例外是 strings ,在这种情况下,它们被视为值类型)。
也就是说,传递给.Remove()的参数必须是非常相同的对象才能在列表中找到(不是碰巧代表同一事物的另一个对象)。

因此, 中排除名为ABC_Export-Cars.zip的文件会更容易:

$packageList = Get-ChildItem "\\path-to-files\*.zip" -Exclude ABC_Export-Cars.zip

使用-Exclude参数可以将特定文件名排除在Get-ChildItem调用之外;请注意,必须使用*.zip通配符作为-Path参数(暗示)的一部分。

如果不是从源头排除的选项,则替代方法是使用-慢-循环 来删除感兴趣的文件信息对象:

$packageList = foreach ($file in $packageList) {
  if ($file.Name -ne 'ABC_Export-Cars.zip') {
     $_ # pass the object through
  }
}

请注意,$packageList结果会收到一个新创建的 array [object[]]),因此没有充分的理由将$packageList键入为{{ 1}}。

一种更为简洁且速度稍快的替代方法是使用 PSv4 + .Where() collection-filtering method

[System.Collections.ArrayList]

在这种情况下,输出集合类型为$packageList = $packageList.Where({ $_.Name -ne 'ABC_Export-Cars.zip' }) ,尽管在大多数情况下它的行为类似于常规数组(或数组列表)。

答案 2 :(得分:0)

Mark Wragg已经回答了您的问题。万一您想使用string MachineName4 = System.Environment.GetEnvironmentVariable("COMPUTERNAME"); 方法,可以使用所需文件的索引将其删除。例如-

Remove

,其中n =要删除的文件的索引