在Powershell中,按记录类型分割大文本文件最有效的方法是什么?

在Powershell中,按记录类型分割大文本文件最有效的方法是什么?,第1张

概述我正在使用Power shell进行一些ETL工作,根据每一行的前三个字符读取压缩文本文件并将其分解出来. 如果我只是过滤输入文件,我可以将过滤的流管理到Out-File并完成.但是我需要将输出重定向到多个目的地,据我所知,这不能用一个简单的管道来完成.我已经在使用.NET Streamreader来读取压缩的输入文件了,我想知道我是否需要使用流程编写输出文件. 天真的版本看起来像这样: whil 我正在使用Power shell进行一些ETL工作,根据每一行的前三个字符读取压缩文本文件并将其分解出来.

如果我只是过滤输入文件,我可以将过滤的流管理到Out-file并完成.但是我需要将输出重定向到多个目的地,据我所知,这不能用一个简单的管道来完成.我已经在使用.NET Streamreader来读取压缩的输入文件了,我想知道我是否需要使用流程编写输出文件.

天真的版本看起来像这样:

while (!$reader.EndOffile) {  $line = $reader.Readline();  switch ($line.substring(0,3) {    "001" {Add-Content "output001.txt" $line}    "002" {Add-Content "output002.txt" $line}    "003" {Add-Content "output003.txt" $line}    }  }

这只是一个坏消息:每行发现,打开,写入和关闭文件一次.输入文件是巨大的500MB怪物.

有没有一个惯用的方法来处理这个有效的w / Powershell结构,还是应该转向.NET流水作者?

有可能使用的(New-Item“path”-type“file”)对象的方法吗?

编辑上下文:

我使用DotNetZip库读取ZIP文件作为流;因此是Streamerer而不是Get-Content / gc.示例代码:

[System.Reflection.Assembly]::LoadFrom("\Path\To\Ionic.Zip.dll") $zipfile = [Ionic.Zip.Zipfile]::Read("\Path\To\file.zip")foreach ($entry in $zipfile) {  $reader = new-object system.io.streamreader $entry.OpenReader();  while (!$reader.EndOffile) {    $line = $reader.Readline();    #do something here  }}

我应该可以dispose()两个$zipfile和$reader,但这是另一个问题!

解决方法 读

至于读取文件和解析,我会用switch语句:

switch -file c:\temp\stackoverflow.testfile2.txt -regex {  "^001" {Add-Content c:\temp\stackoverflow.testfile.001.txt $_}  "^002" {Add-Content c:\temp\stackoverflow.testfile.002.txt $_}  "^003" {Add-Content c:\temp\stackoverflow.testfile.003.txt $_}}

我认为这是更好的做法

>有正则表达式的支持,你没有
必须使子串(可能
昂贵)和
>参数
文件非常方便;)

写作

至于编写输出,我会测试使用流程,但是如果添加内容的性能适合你,我会坚持下去.

添加:
Keith提出使用>>但是,似乎这很慢.此外,它以Unicode编写输出,将文件大小加倍.

看我的测试:

[1]: (measure-command {>>     gc c:\temp\stackoverflow.testfile2.txt  | %{$c = $_; switch ($_.Substring(0,3)) {>>             '001'{$c >> c:\temp\stackoverflow.testfile.001.txt} `>>             '002'{$c >> c:\temp\stackoverflow.testfile.002.txt} `>>             '003'{$c >> c:\temp\stackoverflow.testfile.003.txt}}}>> }).TotalSeconds>>159,1585874[2]: (measure-command {>>     gc c:\temp\stackoverflow.testfile2.txt  | %{$c = $_; switch ($_.Substring(0,3)) {>>             '001'{$c | Add-content c:\temp\stackoverflow.testfile.001.txt} `>>             '002'{$c | Add-content c:\temp\stackoverflow.testfile.002.txt} `>>             '003'{$c | Add-content c:\temp\stackoverflow.testfile.003.txt}}}>> }).TotalSeconds>>9,2696923

差异很大.

只是为了比较:

[3]: (measure-command {>>     $reader = new-object io.streamreader c:\temp\stackoverflow.testfile2.txt>>     while (!$reader.EndOfStream) {>>         $line = $reader.Readline();>>         switch ($line.substring(0,3)) {>>             "001" {Add-Content c:\temp\stackoverflow.testfile.001.txt $line}>>             "002" {Add-Content c:\temp\stackoverflow.testfile.002.txt $line}>>             "003" {Add-Content c:\temp\stackoverflow.testfile.003.txt $line}>>             }>>         }>>     $reader.close()>> }).TotalSeconds>>8,2454369[4]: (measure-command {>>     switch -file c:\temp\stackoverflow.testfile2.txt -regex {>>         "^001" {Add-Content c:\temp\stackoverflow.testfile.001.txt $_}>>         "^002" {Add-Content c:\temp\stackoverflow.testfile.002.txt $_}>>         "^003" {Add-Content c:\temp\stackoverflow.testfile.003.txt $_}>>     }>> }).TotalSeconds8,6755565

补充:我很好奇写作表演..我有点惊讶

[8]: (measure-command {>>     $sw1 = new-object io.streamwriter c:\temp\stackoverflow.testfile.001.txt3b>>     $sw2 = new-object io.streamwriter c:\temp\stackoverflow.testfile.002.txt3b>>     $sw3 = new-object io.streamwriter c:\temp\stackoverflow.testfile.003.txt3b>>     switch -file c:\temp\stackoverflow.testfile2.txt -regex {>>         "^001" {$sw1.Writeline($_)}>>         "^002" {$sw2.Writeline($_)}>>         "^003" {$sw3.Writeline($_)}>>     }>>     $sw1.Close()>>     $sw2.Close()>>     $sw3.Close()>>>> }).TotalSeconds>>0,1062315

速度是80倍.
现在您必须决定 – 如果速度很重要,请使用StreamWriter.如果代码清晰度很重要,请使用Add-Content.

子字典与正则表达式

根据Keith Substring快20%.一如往常.但是,在我的情况下,结果是这样的:

[102]: (measure-command {>>     gc c:\temp\stackoverflow.testfile2.txt  | %{$c = $_; switch ($_.Substring(0,3)) {>>             '001'{$c | Add-content c:\temp\stackoverflow.testfile.001.s.txt} `>>             '002'{$c | Add-content c:\temp\stackoverflow.testfile.002.s.txt} `>>             '003'{$c | Add-content c:\temp\stackoverflow.testfile.003.s.txt}}}>> }).TotalSeconds>>9,0654496[103]: (measure-command {>>     gc c:\temp\stackoverflow.testfile2.txt  | %{$c = $_; switch -regex ($_) {>>             '^001'{$c | Add-content c:\temp\stackoverflow.testfile.001.r.txt} `>>             '^002'{$c | Add-content c:\temp\stackoverflow.testfile.002.r.txt} `>>             '^003'{$c | Add-content c:\temp\stackoverflow.testfile.003.r.txt}}}>> }).TotalSeconds>>9,2563681

所以区别并不重要,对我来说,正则表达式更易于阅读.

总结

以上是内存溢出为你收集整理的在Powershell中,按记录类型分割大文本文件最有效的方法是什么?全部内容,希望文章能够帮你解决在Powershell中,按记录类型分割大文本文件最有效的方法是什么?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1143014.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存