Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 将两个不同的Get ChildItem调用的结果合并到一个变量中,对它们执行相同的处理_Arrays_Powershell_Get Childitem - Fatal编程技术网

Arrays 将两个不同的Get ChildItem调用的结果合并到一个变量中,对它们执行相同的处理

Arrays 将两个不同的Get ChildItem调用的结果合并到一个变量中,对它们执行相同的处理,arrays,powershell,get-childitem,Arrays,Powershell,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 "\\ser

我正试图编写一个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[]”的 “System.IO.FileInfo”


我最感兴趣的是,对于这种情况,什么是正确的方法。我意识到我的代码是一种非常有效的方法——如果有一种更强大的方法来完成同样的任务,我完全赞成。关键是,
$loc#
的数量可能会随着时间的推移而变化,因此在生成的代码中添加和删除一两个应该很容易。

不确定您是否需要一个通用列表。您可以只使用PowerShell阵列,例如:

$items  = @(Get-ChildItem '\\server\C$\Program Files (x86)\Data1\' -r)
$items += @(Get-ChildItem '\\server\C$\Web\DataStorage\' -r)
PowerShell阵列可以使用
+=

连接,Keith的答案是PowerShell的方式:只需使用@(…)+@(…)。 如果确实需要类型安全列表[IO.FileInfo],则需要使用AddRange,并将对象数组强制转换为FileInfo数组——还需要确保不获取任何DirectoryInfo对象,否则需要使用IO.FileSystemInfo作为列表类型:

因此,避免使用目录:

$items = New-Object Collections.Generic.List[IO.FileInfo]
$items.AddRange( ([IO.FileSystemInfo[]](ls '\\server\C$\Program Files (x86)\Data1\' -r | Where { -not $_.PSIsContainer } )) )
$items.AddRange( ([IO.FileSystemInfo[]](ls '\\server\C$\Web\DataStorage\' -r | Where { -not $_.PSIsContainer } )) )
或者使用FileSystemInfo(FileInfo和DirectoryInfo的公共基类):


下面是一种可能更像PowerShell的方法,它根本不需要部分串联或向结果中显式添加项:

# Collect the results by two or more calls of Get-ChildItem
# and perhaps do some other job (but avoid unwanted output!)
$result = .{

    # Output items
    Get-ChildItem C:\TEMP\_100715_103408 -Recurse

    # Some other job
    $x = 1 + 1

    # Output some more items
    Get-ChildItem C:\TEMP\_100715_110341 -Recurse

    #...
}

# Process the result items
$result
但是脚本块中的代码应该编写得更仔细一些,以避免不必要的输出与文件系统项混合在一起

编辑:或者,也许更有效,我们可以代替
{…}
使用
@(…)
$(…)
其中
..
表示包含多个
从Get-help Get-ChildItem调用
Get-ChildItem

: -路径 指定一个或多个位置的路径。允许使用通配符。默认位置是当前目录(.)


-Filter
-Include
性能更好,因此如果没有很多不同的扩展名,只需将两个过滤列表连接起来可能会更快

$files=Get ChildItem-Path“H:\stash\”-Filter*.rdlc-Recurse
$files+=Get ChildItem-Path“H:\stash\”-Filter*.rdl-Recurse
我将输出与计时器进行了比较,如下所示:

$stopwatch=[System.Diagnostics.stopwatch]::StartNew()
#在这里做事
$stopwatch.Stop()
写入主机“$([Math]::Round($stopwatch.appeased.TotalSeconds))秒数”

这是最好、最简洁的方法,我应该补充一点,您现在可以(在PS4+中)使用
-file
打开
Get ChildItem
(别名
ls
)而不是使用
| where object{-而不是$\pscontainer}
我实际上是指您的/Keith解决方案
@(…)+@(…)(…)
:-)很棒的解决方案!我有一个类似的问题,但我使用JSON对象,并使用您的强制转换策略将JSON转换为
PSCustomObject
数组。好主意!也许应该解释一下对
@()
的需要(?)。如果输出仅包含一个项,则Get ChildItem不输出数组。若这不是PS,我们需要检查第一个输出的类型,数组和对象,然后相应地处理它。在PS中,
(@(@('s','d'))[0].GetType()
是字符串,这意味着创建仅包含一个数组的数组的意图将被忽略。在本例中,如果第一行只生成一个项,并且未使用@(),则$items将是一个对象,并且尝试将数组连接到对象将导致第二行出错@()第二行不需要,因为您可以通过相同的
+=
@papo |
Get-ChildItem将对象连接到数组,也可以将数组连接到数组。如果输出仅包含一个项,则该项不输出数组。
但是,它可以工作(至少在我的系统上,PS v5.1.14393.3471)。我可以毫无问题地做到这一点:
$Files=@(gci-Filter“$BuildName-$SemanticVersion*.nupkg”)$文件+=@(gci-Filter“Setup.exe”)$Files
@InteXX抱歉没有提及我的评论是对Peter评论的回答。您的示例与Keith相似,所以应该是这样的,但是如果您像Peter所问的那样省略@(),它可能会行为不端。PS的自动类型很好,但可能会产生问题。如果需要数组,请具体说明。或者,您可能最终会出现错误,或者在不同的情况下,您可能会遇到一个数组条目数组,而这是不需要的。我遵循规则,如果是剧本,就要非常简洁。@papo |啊,好的。明白了。这是有道理的。事实上,我最终选择了罗曼的版本,从下面开始<代码>$Files=@(gci-Path$ReleaseDirectory-Filter“$BuildName-$SemanticVersion*.nupkg”;gci-Path$ReleaseDirectory-Filter“Setup.exe”gci-Path$ReleaseDirectory-Filter“release”)$文件简洁美观,效果极佳。
# Collect the results by two or more calls of Get-ChildItem
# and perhaps do some other job (but avoid unwanted output!)
$result = .{

    # Output items
    Get-ChildItem C:\TEMP\_100715_103408 -Recurse

    # Some other job
    $x = 1 + 1

    # Output some more items
    Get-ChildItem C:\TEMP\_100715_110341 -Recurse

    #...
}

# Process the result items
$result
$items = get-childitem '\\server\C$\Program Files (x86)\Data1\','\\server\C$\Web\DataStorage\' -Recurse