将两个不同的 Get-ChildItem 调用的结果合并到单个变量中以对它们进行相同的处理
我正在尝试编写一个 PowerShell 脚本来从多个目录构建文件列表。将所有目录添加到主列表后,我想对所有文件进行相同的处理。
这就是我所拥有的:
$items = New-Object Collections.Generic.List[IO.FileInfo]
$loc1 = @(Get-ChildItem -Path "\\server\C$\Program Files (x86)\Data1\" -Recurse)
$loc2 = @(Get-ChildItem -Path "\\server\C$\Web\DataStorage\" -Recurse)
$items.Add($loc1) # This line fails (the next also fails)
$items.Add($loc2)
# Processing code is here
它因以下错误而失败:
无法转换参数“0” 值:“System.Object[]”,用于“添加”到 输入“System.IO.FileInfo”:“不能 转换“System.Object[]”值 类型为“System.Object[]”的类型 “系统.IO.文件信息”。”
我最感兴趣的是这种情况的正确方法是什么。我意识到我的代码非常C 方法——如果有更多的 PowerShell 方法来完成相同的任务,我完全赞成。关键是数字$loc#'s
的数量可能会随着时间的推移而发生变化,因此在生成的代码中添加和删除一两个应该很容易。
I'm trying to write a PowerShell script to build a list of files, from several directories. After all directories have been added to the main list, I'd like to do the same processing on all files.
This is what I have:
$items = New-Object Collections.Generic.List[IO.FileInfo]
$loc1 = @(Get-ChildItem -Path "\\server\C$\Program Files (x86)\Data1\" -Recurse)
$loc2 = @(Get-ChildItem -Path "\\server\C$\Web\DataStorage\" -Recurse)
$items.Add($loc1) # This line fails (the next also fails)
$items.Add($loc2)
# Processing code is here
which fails with this error:
Cannot convert argument "0", with
value: "System.Object[]", for "Add" to
type "System.IO.FileInfo": "Cannot
convert the "System.Object[]" va lue
of type "System.Object[]" to type
"System.IO.FileInfo"."
I am mostly interested in what is the correct approach for this type of situation. I realize that my code is a very C way of doing it -- if there is a more PowerShell way to acomplish the same task, I'm all for it. The key, is that the number of $loc#'s
may change over time, so adding and removing one or two should be easy in the resulting code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不确定您是否需要这里的通用列表。您可以只使用 PowerShell 数组,例如:
可以使用
+=
连接 PowerShell 数组。Not sure you need a generic list here. You can just use a PowerShell array e.g.:
PowerShell arrays can be concatenated using
+=
.从 get-help get-childitem 中:
-小路
指定到一个或多个位置的路径。允许使用通配符。默认位置是当前目录 (.)。
From get-help get-childitem:
-Path
Specifies a path to one or more locations. Wildcards are permitted. The default location is the current directory (.).
这里有一些可能更类似于 PowerShell 的方法,根本不需要部分串联或显式向结果添加项目:
但是应该更仔细地编写脚本块内的代码,以避免不需要的输出与文件系统项目混合在一起。
编辑:或者,也许更有效的是,我们可以代替
.{ ... }
使用
@( ... )
或$( ... )
其中...
代表包含多个的代码调用
Get-ChildItem
。Here is some perhaps even more PowerShell-ish way that does not need part concatenation or explicit adding items to the result at all:
But the code inside the script block should be written slightly more carefully to avoid unwanted output mixed together with file system items.
EDIT: Alternatively, and perhaps more effectively, instead of
.{ ... }
we canuse
@( ... )
or$( ... )
where...
stands for the code containing severalcalls of
Get-ChildItem
.Keith 的答案是 PowerShell 方式:只需使用 @(...)+@(...)。
如果您确实想要一个类型安全的 List[IO.FileInfo],那么您需要使用 AddRange,并将对象数组转换为 FileInfo 数组 - 您还需要确保您没有获得任何 DirectoryInfo 对象,否则您需要使用 IO.FileSystemInfo 作为列表类型:
因此,避免使用目录:
或使用 FileSystemInfo(FileInfo 和 DirectoryInfo 的公共基类):
Keith's answer is the PowerShell way: just use @(...)+@(...).
If you actually do want a typesafe List[IO.FileInfo], then you need to use AddRange, and cast the object array to a FileInfo array -- you also need to make sure you don't get any DirectoryInfo objects, or else you need to use IO.FileSystemInfo as your list type:
So, avoid directories:
Or use FileSystemInfo (the common base class of FileInfo and DirectoryInfo):
-Filter
比-Ininclude
性能更高,因此,如果您没有很多不同的扩展名,那么简单地连接两个过滤列表可能会更快。我将输出与这样的计时器进行了比较:
-Filter
is more performant than-Include
, so if you don't have a lot of different extensions, simply concatenating two filtered lists might be faster.I compared the output with a timer like this: