Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.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
多线程PowerShell脚本可更快地从大型XML文件中提取数据_Powershell - Fatal编程技术网

多线程PowerShell脚本可更快地从大型XML文件中提取数据

多线程PowerShell脚本可更快地从大型XML文件中提取数据,powershell,Powershell,下面的脚本按预期工作以获得所需的输出,但处理大型XML文件(2GB及以上)需要很长时间。请专家就如何通过多线程或在powershell脚本中使用其他技术来提高速度提出建议 参考文章-了解以下脚本的逻辑: 输出: PRIORITY KEY HITS -------- --- ---- 1 1 1 -3 2 2 -14 2 3 <ABC-FOF-PROCESS> <H> <PRIORITY>-

下面的脚本按预期工作以获得所需的输出,但处理大型XML文件(2GB及以上)需要很长时间。请专家就如何通过多线程或在powershell脚本中使用其他技术来提高速度提出建议

参考文章-了解以下脚本的逻辑:

输出:

PRIORITY KEY HITS
-------- --- ----
       1   1    1
      -3   2    2
     -14   2    3
<ABC-FOF-PROCESS>
<H>
 <PRIORITY>-14</PRIORITY>
 <KEY>F637A146-3437AB82-BA659D4A-17AC7FBF</KEY>
</H>
<H>
 <PRIORITY>-14</PRIORITY>
 <KEY>F637A146-3437AB82-BA659D4A-17AC7FBF</KEY>
</H>
<H>
 <PRIORITY>-3</PRIORITY>
 <KEY>D6306210-CF424F11-8E2D3496-E6CE1CA7</KEY>
</H>
<H>
 <PRIORITY>1</PRIORITY>
 <KEY>D6306210-CF424F11-8E2D3496-E6CE1CA7</KEY>
</H>
<H>
 <PRIORITY>-3</PRIORITY>
 <KEY>4EFR02B4-ADFDAF12-3C123II2-ADAFADFD</KEY>
</H>
<H>
 <PRIORITY>-14</PRIORITY>
 <KEY>5D2702B2-ECE8F1FB-3CEC3229-5FE4C4BC</KEY>
</H>
</ABC-FOF-PROCESS>
xml:

PRIORITY KEY HITS
-------- --- ----
       1   1    1
      -3   2    2
     -14   2    3
<ABC-FOF-PROCESS>
<H>
 <PRIORITY>-14</PRIORITY>
 <KEY>F637A146-3437AB82-BA659D4A-17AC7FBF</KEY>
</H>
<H>
 <PRIORITY>-14</PRIORITY>
 <KEY>F637A146-3437AB82-BA659D4A-17AC7FBF</KEY>
</H>
<H>
 <PRIORITY>-3</PRIORITY>
 <KEY>D6306210-CF424F11-8E2D3496-E6CE1CA7</KEY>
</H>
<H>
 <PRIORITY>1</PRIORITY>
 <KEY>D6306210-CF424F11-8E2D3496-E6CE1CA7</KEY>
</H>
<H>
 <PRIORITY>-3</PRIORITY>
 <KEY>4EFR02B4-ADFDAF12-3C123II2-ADAFADFD</KEY>
</H>
<H>
 <PRIORITY>-14</PRIORITY>
 <KEY>5D2702B2-ECE8F1FB-3CEC3229-5FE4C4BC</KEY>
</H>
</ABC-FOF-PROCESS>

-14
F637A146-3437AB82-BA659D4A-17AC7FBF
-14
F637A146-3437AB82-BA659D4A-17AC7FBF
-3
D6306210-CF424F11-8E2D3496-E6CE1CA7
1.
D6306210-CF424F11-8E2D3496-E6CE1CA7
-3
4EFR02B4-ADFDAF12-3C123II2-ADAFADFD
-14
5D2702B2-ECE8F1FB-3CEC3229-5FE4C4BC

我想这是一个例子,重点放在单个命令()上,而不是完成解决方案

总的来说,我建议您查看整个解决方案,而不仅仅是单个语句

在您的例子中,如果仅仅因为要使用
Foreach
语句而需要实例化一个脚本并使用调用该脚本,您可能会超出目标:

对于您提供的小文件,
这(将管道与
ForEach对象一起使用)

显示速度通常快于此(使用
ForEach
语句和Call操作符):


由于
Sort Object
cmdlet的性质(所有对象都必须能够对其进行排序),它需要暂停管道以对其进行重新排序,出于同样的原因,多线程方法可能没有多大意义。

如果xml是固定格式,您可以逐行读取文件,并在运行时调整结果

它不是并行的,它不如使用xml解析功能那么健壮,它不会赢得任何美貌奖,但它应该非常快

$hits = @{} # Hashtable containing number of hits per priority
$keys = @{} # Hashtable containing unique keys per priority
switch -Regex -File $env:temp\test.xml
{
    '^\s+<PRIORITY>(?<priority>[-]?\d+)'
    {
        $currentPriority = $matches.Priority
        $hits[$currentPriority] = $hits[$currentPriority]+1
        continue
    }
    '^\s+<KEY>(?<key>[\w-]+)'
    {
        $currentKey = $matches.Key
        if ($keys[$currentPriority] -eq $null) {$keys[$currentPriority] = @{}}
        $keys[$currentPriority][$currentKey] = $null
    }
}

$hits.GetEnumerator() | % {
    [PSCustomObject]@{
        PRIORITY = [int]$_.Key
        KEY = $keys[$_.Key].Count
        HITS = [int]$_.Value
    }
} | Sort PRIORITY -Descending

现在需要多长时间?什么样的时间是可以接受的?使用此脚本处理3 GB文件大约需要9个小时,解决此问题的主要目标是使用此脚本在很短的时间内找到统计信息,最有可能在15分钟内找到,而不是将XML加载到数据库中,然后使用sql查找统计信息(将文件加载到数据库大约需要12小时)。将整个XML转换为CSV格式,并带有列作为优先级和键。加载到数据库中并在SQL中进行求和。不要在数据库中使用XML数据类型,这样效率很低。@vonPryz我不想将数百万条记录加载到数据库中以获取此统计数据,相反,我需要动态获取统计数据,因此数据库管理将减少。因为此脚本t尚未最终确定,目前我们正在将XML加载到DB,但不幸的是,由于我们为该解决方案设置的软件限制,我们无法将XML转换为CSV,正如您所说,这将更加有效。感谢您的回答,我将很快对此进行测试,并将分享我的反馈。我能够启动脚本并使用它运行代码中有一点小小的调整。您共享的脚本有助于解决前所未有的问题,因为输入XML具有STX.etc等控制字符,因为解决方案基于regex,这是有益的。而且脚本在完成任务方面非常快。早些时候,我不得不坚持备份计划,以完全依赖python脚本传统上被认为是高效的,但在我的例子中,你的脚本为我工作。谢谢!用一个大的XML文件(2.4GB)测试它在16分钟内完成,这是令人惊讶的。我的一个关键测试用例,重点是脚本的逻辑,失败了-测试用例的详细信息在我的另一篇文章中更新。为了解决这个问题,我将键和优先级推到一个哈希表,然后再次键和点击到另一个哈希表,我让循环通过两个表来分组并获得最大值嗯,优先级和点击总数。谢谢你们的回答,我会很快测试,我会分享我的反馈。
$hits = @{} # Hashtable containing number of hits per priority
$keys = @{} # Hashtable containing unique keys per priority
switch -Regex -File $env:temp\test.xml
{
    '^\s+<PRIORITY>(?<priority>[-]?\d+)'
    {
        $currentPriority = $matches.Priority
        $hits[$currentPriority] = $hits[$currentPriority]+1
        continue
    }
    '^\s+<KEY>(?<key>[\w-]+)'
    {
        $currentKey = $matches.Key
        if ($keys[$currentPriority] -eq $null) {$keys[$currentPriority] = @{}}
        $keys[$currentPriority][$currentKey] = $null
    }
}

$hits.GetEnumerator() | % {
    [PSCustomObject]@{
        PRIORITY = [int]$_.Key
        KEY = $keys[$_.Key].Count
        HITS = [int]$_.Value
    }
} | Sort PRIORITY -Descending
PRIORITY KEY    HITS
-------- ---    ----
       1   1 1000000
      -3   2 2000000
     -14   2 3000000

$timer

IsRunning Elapsed          ElapsedMilliseconds ElapsedTicks
--------- -------          ------------------- ------------
    False 00:02:25.7186698              145718    413249113