Powershell ArrayList 删除带有特殊字符的项目
Powershell ArrayList remove item with 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
删除不适用于此类项目,但它在数组中。使用一个简单的数组,例如包含 "A"、"B"、"C" 它有效。 “_”或“-”字符需要特殊处理吗?
问题是您的 ArrayList 包含 Get-ChildItem
返回的 FileInfo 对象集合。因此 none 这些项目与您要删除的字符串相匹配。显然,当您使用字符串集合 (a,b,c) 时,您可以匹配要删除的字符串。
您可能只需要 ArrayList 中的文件名,在这种情况下,请执行以下操作:
[System.Collections.ArrayList]$packageList = (Get-ChildItem "\path-to-files" -Filter *.zip).name
.Remove
操作应该适用于指定的文件名。
Mark Wragg 已经回答了你的问题。以防万一如果你想使用 Remove
方法,你可以使用所需文件的索引将其删除。例如 -
$packageList.Remove($packageList[n])
其中 n = 您要删除的文件的索引
很好地解释了您尝试的问题,并仅根据名称提供了一个有效的替代方案。
如果您确实想收集 Get-ChildItem
在 $packageList
中输出的 [System.IO.FileInfo]
个实例(而不仅仅是它们的 .Name
属性 值),您基于 .Remove()
的方法 无法 起作用,因为您将不得不通过 非常相同的 [System.IO.FileInfo]
实例 已经是数组列表的一部分,以便成功删除它。
原因是 .Remove()
方法使用 引用相等性 来查找作为 .NET reference types 实例的列表元素(唯一的例外是 字符串,在此上下文中被视为值类型)。
也就是说,传递给 .Remove()
的参数必须是 完全相同的对象 才能在列表中找到(而不是恰好代表同一事物的另一个对象)。
因此,在 source:[=35 中排除名为 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
结果接收到一个新创建的 数组 ([object[]]
),因此没有充分的理由键入 $packageList
作为 [System.Collections.ArrayList]
开头。
一种更简洁且速度稍快的替代方法是使用 PSv4+ .Where()
collection-filtering method:
$packageList = $packageList.Where({ $_.Name -ne 'ABC_Export-Cars.zip' })
在这种情况下,输出集合类型是 [System.Collections.ObjectModel.Collection[psobject]]
,但在大多数情况下,它的行为类似于常规数组(或数组列表)。
我这样做
[System.Collections.ArrayList]$packageList = (Get-ChildItem "\path-to-files" -Filter *.zip )
Write-Host $packageList
$packageList.Remove("ABC_Export-Cars.zip")
Write-Host $packageList
删除不适用于此类项目,但它在数组中。使用一个简单的数组,例如包含 "A"、"B"、"C" 它有效。 “_”或“-”字符需要特殊处理吗?
问题是您的 ArrayList 包含 Get-ChildItem
返回的 FileInfo 对象集合。因此 none 这些项目与您要删除的字符串相匹配。显然,当您使用字符串集合 (a,b,c) 时,您可以匹配要删除的字符串。
您可能只需要 ArrayList 中的文件名,在这种情况下,请执行以下操作:
[System.Collections.ArrayList]$packageList = (Get-ChildItem "\path-to-files" -Filter *.zip).name
.Remove
操作应该适用于指定的文件名。
Mark Wragg 已经回答了你的问题。以防万一如果你想使用 Remove
方法,你可以使用所需文件的索引将其删除。例如 -
$packageList.Remove($packageList[n])
其中 n = 您要删除的文件的索引
如果您确实想收集 Get-ChildItem
在 $packageList
中输出的 [System.IO.FileInfo]
个实例(而不仅仅是它们的 .Name
属性 值),您基于 .Remove()
的方法 无法 起作用,因为您将不得不通过 非常相同的 [System.IO.FileInfo]
实例 已经是数组列表的一部分,以便成功删除它。
原因是 .Remove()
方法使用 引用相等性 来查找作为 .NET reference types 实例的列表元素(唯一的例外是 字符串,在此上下文中被视为值类型)。
也就是说,传递给 .Remove()
的参数必须是 完全相同的对象 才能在列表中找到(而不是恰好代表同一事物的另一个对象)。
因此,在 source:[=35 中排除名为 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
结果接收到一个新创建的 数组 ([object[]]
),因此没有充分的理由键入 $packageList
作为 [System.Collections.ArrayList]
开头。
一种更简洁且速度稍快的替代方法是使用 PSv4+ .Where()
collection-filtering method:
$packageList = $packageList.Where({ $_.Name -ne 'ABC_Export-Cars.zip' })
在这种情况下,输出集合类型是 [System.Collections.ObjectModel.Collection[psobject]]
,但在大多数情况下,它的行为类似于常规数组(或数组列表)。