我正在使用PowerShell进行一些ETL工作,读取压缩的文本文件并根据每行的前三个字符将其拆分出来。
如果我只是过滤输入文件,我可以将过滤后的流传递到Out-File并完成操作。但我需要将输出重定向到多个目标,据我所知,这不能通过简单的管道实现。我已经在使用.NET streamreader读取压缩的输入文件,我想知道是否需要使用streamwriter来编写输出文件。
天真的版本看起来像这样:
那看起来很不好:每一行都要找、打开、写入和关闭一个文件。输入文件非常大,超过500MB。
有没有使用Powershell结构处理这个问题的惯用方法,或者我应该转向.NET streamwriter?
是否可以使用(New-Item "path" -type "file")对象的方法来处理这个问题?
编辑内容如下:
我正在使用DotNetZip库将ZIP文件读取为流;因此使用streamreader而不是Get-Content/gc。示例代码:
如果我只是过滤输入文件,我可以将过滤后的流传递到Out-File并完成操作。但我需要将输出重定向到多个目标,据我所知,这不能通过简单的管道实现。我已经在使用.NET streamreader读取压缩的输入文件,我想知道是否需要使用streamwriter来编写输出文件。
天真的版本看起来像这样:
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。
有没有使用Powershell结构处理这个问题的惯用方法,或者我应该转向.NET streamwriter?
是否可以使用(New-Item "path" -type "file")对象的方法来处理这个问题?
编辑内容如下:
我正在使用DotNetZip库将ZIP文件读取为流;因此使用streamreader而不是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
}
}
我应该释放 $zipfile 和 $reader,但这是另一个问题!
StreamWriter
的速度,这是生成测试文件的代码:1..5000 | % { $n = Get-Random -Min 1 -Max 4; $x=1..(Get-Random -Min 20 -Max 150) | % { ([char](Get-Random -Min 65 -Max 120)) }; $x = $x -join ""; '{0:000} {1}' -f $n,$x } | Add-Content C:\temp\stackoverflow.testfile.txt
(现在行数为5000)。 - stejswitch -file
结构,但知道在处理未压缩文件时它是可用的很好。 - Peter Radocchia