在Powershell中,按记录类型分割大文本文件最有效的方法是什么?
我正在使用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("PathToIonic.Zip.dll") $zipfile = [Ionic.Zip.ZipFile]::Read("PathToFile.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:tempstackoverflow.testfile2.txt -regex { "^001" {Add-Content c:tempstackoverflow.testfile.001.txt $_} "^002" {Add-Content c:tempstackoverflow.testfile.002.txt $_} "^003" {Add-Content c:tempstackoverflow.testfile.003.txt $_} } 我认为这是更好的做法 >有正则表达式的支持,你没有 写作 至于编写输出,我会测试使用流程,但是如果添加内容的性能适合你,我会坚持下去. 添加: 看我的测试: [1]: (measure-command { >> gc c:tempstackoverflow.testfile2.txt | %{$c = $_; switch ($_.Substring(0,3)) { >> '001'{$c >> c:tempstackoverflow.testfile.001.txt} ` >> '002'{$c >> c:tempstackoverflow.testfile.002.txt} ` >> '003'{$c >> c:tempstackoverflow.testfile.003.txt}}} >> }).TotalSeconds >> 159,1585874 [2]: (measure-command { >> gc c:tempstackoverflow.testfile2.txt | %{$c = $_; switch ($_.Substring(0,3)) { >> '001'{$c | Add-content c:tempstackoverflow.testfile.001.txt} ` >> '002'{$c | Add-content c:tempstackoverflow.testfile.002.txt} ` >> '003'{$c | Add-content c:tempstackoverflow.testfile.003.txt}}} >> }).TotalSeconds >> 9,2696923 差异很大. 只是为了比较: [3]: (measure-command { >> $reader = new-object io.streamreader c:tempstackoverflow.testfile2.txt >> while (!$reader.EndOfStream) { >> $line = $reader.ReadLine(); >> switch ($line.substring(0,3)) { >> "001" {Add-Content c:tempstackoverflow.testfile.001.txt $line} >> "002" {Add-Content c:tempstackoverflow.testfile.002.txt $line} >> "003" {Add-Content c:tempstackoverflow.testfile.003.txt $line} >> } >> } >> $reader.close() >> }).TotalSeconds >> 8,2454369 [4]: (measure-command { >> switch -file c:tempstackoverflow.testfile2.txt -regex { >> "^001" {Add-Content c:tempstackoverflow.testfile.001.txt $_} >> "^002" {Add-Content c:tempstackoverflow.testfile.002.txt $_} >> "^003" {Add-Content c:tempstackoverflow.testfile.003.txt $_} >> } >> }).TotalSeconds 8,6755565 补充:我很好奇写作表演..我有点惊讶 [8]: (measure-command { >> $sw1 = new-object io.streamwriter c:tempstackoverflow.testfile.001.txt3b >> $sw2 = new-object io.streamwriter c:tempstackoverflow.testfile.002.txt3b >> $sw3 = new-object io.streamwriter c:tempstackoverflow.testfile.003.txt3b >> switch -file c:tempstackoverflow.testfile2.txt -regex { >> "^001" {$sw1.WriteLine($_)} >> "^002" {$sw2.WriteLine($_)} >> "^003" {$sw3.WriteLine($_)} >> } >> $sw1.Close() >> $sw2.Close() >> $sw3.Close() >> >> }).TotalSeconds >> 0,1062315 速度是80倍. 子字典与正则表达式 根据Keith Substring快20%.一如往常.但是,在我的情况下,结果是这样的: [102]: (measure-command { >> gc c:tempstackoverflow.testfile2.txt | %{$c = $_; switch ($_.Substring(0,3)) { >> '001'{$c | Add-content c:tempstackoverflow.testfile.001.s.txt} ` >> '002'{$c | Add-content c:tempstackoverflow.testfile.002.s.txt} ` >> '003'{$c | Add-content c:tempstackoverflow.testfile.003.s.txt}}} >> }).TotalSeconds >> 9,0654496 [103]: (measure-command { >> gc c:tempstackoverflow.testfile2.txt | %{$c = $_; switch -regex ($_) { >> '^001'{$c | Add-content c:tempstackoverflow.testfile.001.r.txt} ` >> '^002'{$c | Add-content c:tempstackoverflow.testfile.002.r.txt} ` >> '^003'{$c | Add-content c:tempstackoverflow.testfile.003.r.txt}}} >> }).TotalSeconds >> 9,2563681 所以区别并不重要,对我来说,正则表达式更易于阅读. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |