Powershell foreach对象脚本替代方案,可加快执行速度

Powershell foreach对象脚本替代方案,可加快执行速度,powershell,Powershell,我有下面的代码,做我需要的,但它是缓慢的,我想知道是否有任何更快的替代品,可以做同样的事情 $array2= ('italy', 'mexico', 'australia') $pattern = '(?:total residents\s: )\W(\d+)\W' $array = $array2 | ForEach-Object { $array3 = Get-ChildItem -Path $path -Recurse | Select-string -Pattern $_ -

我有下面的代码,做我需要的,但它是缓慢的,我想知道是否有任何更快的替代品,可以做同样的事情

$array2= ('italy', 'mexico', 'australia')

$pattern = '(?:total residents\s: )\W(\d+)\W'

$array = $array2 | ForEach-Object {
    $array3 = Get-ChildItem -Path $path -Recurse | Select-string -Pattern $_ -SimpleMatch -Context 9, 0 | ForEach-Object { 
        $_.Context.PreContext
        $_.Line
        $_.Context.PostContext
    }
    $array3 | Select-String -Pattern $pattern | ForEach-Object { $_.Matches.Groups[1].Value }
}
$array2最多可以有10个元素,这只是3个元素的示例

文件包含以下格式的数据点表示我不需要的其他信息这只是其中的一部分,所以国家线比居民总数低9行

居民总数:15899630 . . . . . . . . 国家:意大利

============================================================

上述脚本的输出:

15899630 2442110
1500000

了解regex模式和数据的输入格式可能很有用,但根据提供的示例脚本,我建议:

只读取每个文件一次 将第二次选择字符串调用替换为-match/$matches 比如:

foreach($file in Get-ChildItem -Path $path -Recurse -File){
    foreach($item in $array2){
        $file |Select-String -Pattern $item -SimpleMatch -Context 9, 0 |ForEach-Object { 
            $_.Context.PreContext
            $_.Line
        } |ForEach-Object {
            if($_ -match $pattern){
                $Matches[1]
            }
        }
    }
}

了解regex模式和数据的输入格式可能很有用,但根据提供的示例脚本,我建议:

只读取每个文件一次 将第二次选择字符串调用替换为-match/$matches 比如:

foreach($file in Get-ChildItem -Path $path -Recurse -File){
    foreach($item in $array2){
        $file |Select-String -Pattern $item -SimpleMatch -Context 9, 0 |ForEach-Object { 
            $_.Context.PreContext
            $_.Line
        } |ForEach-Object {
            if($_ -match $pattern){
                $Matches[1]
            }
        }
    }
}
由于selectstring接受一个模式数组,所以我看不出有什么理由对这样的数组进行管道处理

这可能不起作用,但我认为它朝着正确的方向发展:

注:结合以下Mathias R.Jessen的部分工作:

$Result =
Get-ChildItem $Path -Recurse -File |
Select-String -Pattern $Array2 -SimpleMatch -Context 9, 0 |
ForEach-Object{
    $_.Context.PreContext
    $_.Line
    } |
ForEach-Object{
    If( $_ -match $pattern ) { $_.Matches[1] }
}
由于selectstring接受一个模式数组,所以我看不出有什么理由对这样的数组进行管道处理

这可能不起作用,但我认为它朝着正确的方向发展:

注:结合以下Mathias R.Jessen的部分工作:

$Result =
Get-ChildItem $Path -Recurse -File |
Select-String -Pattern $Array2 -SimpleMatch -Context 9, 0 |
ForEach-Object{
    $_.Context.PreContext
    $_.Line
    } |
ForEach-Object{
    If( $_ -match $pattern ) { $_.Matches[1] }
}

您的问题中没有足够的详细信息来创建正确的答案并对其进行测试,但根据文件的内容、数组和$Pattern缓存匹配的“我的帮助”:

这通常是您可能采取的方法,但无法测试:


请注意,我完全基于您问题中的示例,甚至没有尝试容纳其他人的有效答案,我建议您尝试组合这些答案。

您的问题中没有足够的详细信息来创建正确的答案并对其进行测试,但根据您文件的内容缓存匹配我的帮助,数组和$Pattern:

这通常是您可能采取的方法,但无法测试:


请注意,我完全基于您问题中的示例,甚至没有尝试容纳其他人的有效答案,我建议您尝试合并。

如果您将Get ChildItem-Path$Path-Recurse存储在变量中,而不是为每个模式调用它,会怎么样?为了改进这一点,您需要告诉我们更多关于瓶颈的信息。例如:多少个$array[2]?你有多少个文件?array2通常有5到14个元素我将每个元素作为模式来获取一个字符串,该字符串通过行数与每个模式相关。因此,在上下文中,我只匹配一个文件路径中的元素,即$path。你正在读取相同的文件数百万次,这是代码中比较慢的部分。只读取一个文件并在模式上迭代instead@iRon-我编辑了这篇文章,现在更清楚了,您可以测试代码。如果您将Get ChildItem-Path$Path-Recurse存储在一个变量中,而不是为每个模式调用它,会怎么样?为了改进这一点,您需要告诉我们更多关于瓶颈的信息。例如:多少个$array[2]?你有多少个文件?array2通常有5到14个元素我将每个元素作为模式来获取一个字符串,该字符串通过行数与每个模式相关。因此,在上下文中,我只匹配一个文件路径中的元素,即$path。你正在读取相同的文件数百万次,这是代码中比较慢的部分。只读取一个文件并在模式上迭代instead@iRon-我编辑了这篇文章,现在它更清晰了,你可以测试代码。这比以前快了3倍,非常感谢,请解释一下为什么我的代码如此之慢,而这是非常快的。我是powershell的新手,这将帮助我再次感谢您。@3N16M4-管道天生比foreach这样的标准循环慢。另外,ForEach对象非常非常灵活。。。这意味着它有点慢。因此,foreach循环通常比使用管道和FE-O快整整一个数量级。@Lee_Dailey+我们允许文件系统缓存通过重复访问相同的文件而不是旋转文件来完成它的工作,这比使用管道和FE-O快了3倍,非常感谢,请解释一下为什么我的代码如此之慢,而这是非常快的。我是powershell的新手,这将帮助我再次感谢您。@3N16M4-管道天生比foreach这样的标准循环慢。另外,ForEach对象非常非常灵活。。。这意味着它有点慢。因此,foreach循环通常比使用管道和FE-O快整整一个数量级
通过重复访问相同的文件,而不是在所有文件中旋转,您不会将$\u$array2传递给GetMatches@Mathias,谢谢你的评论。您是对的,当前项$应该是这个示例中的键,我已经更新了示例,您没有将$数组2传递给它GetMatches@Mathias,谢谢你的评论。您是对的,当前项$应该是本示例中的键,我已经更新了示例