Powershell行计入带有大量文本文件的csv

时间:2014-03-06 22:37:49

标签: powershell csv powershell-v2.0

问候光荣的同志,

我需要再次借助你的才华来最大化我的解决方案能力。

我必须使用powershell来遍历大量文本文件的目录(在某些情况下为20 GB),提取文件名,行计数和创建日期,然后将该信息输出到csv中。

到目前为止,这是我的代码:

$fileEntries = [IO.Directory]::GetFiles("T:\frg\working"); 
foreach($fileName in $fileEntries) 
{ 
    $count = 0
    $filedate = (Get-Date).Date
    $reader = New-Object IO.StreamReader $filename
    while($reader.ReadLine() -ne $null){$count++}
    $reader.close()
    #Get-Content $filename | %{$lines++}
    [Console]::Writeline($filename+" "+$count+" "+ $filedate);

}

获取日期只是一个临时填充,直到我可以获得文件创建日期。

目前输出类似于:

T:\frg\working\file1.txt 90055 03/06/2014 00:00:00
T:\frg\working\file2.txt 6419616 03/06/2014 00:00:00

但是对于我的生活,我无法成功地将其传递给csv。

我尝试使用自定义属性设置对象并输出到该对象,但它说管道是空的。

文件的大小阻止使用Import-csv选项(将20GB导入内存会导致一些问题)。如果我可以通过扩展来过滤它也会很整洁,但如果没有,我可以解决它。

任何指示都将不胜感激,谢谢你。

3 个答案:

答案 0 :(得分:3)

试试这个:

$fileEntries = [IO.Directory]::GetFiles("T:\frg\working")

$RecordCounts = 
  foreach($fileName in $fileEntries) 
   { 
    $count = 0
    $filedate = (Get-Date).Date
    Get-Content $fileName -ReadCount 1000 |
     foreach {$count += $_.count}

   New-Object psobject -Property @{FileName = $fileName;Count = $count;FileDate = $filedate}
 }

 $RecordCounts | Export-Csv c:\somedir\RecordCounts.csv

编辑:  针对1GB超过1200万行的1GB文件测试3个发布的解决方案:

$testfile = 'c:\testfiles\bigfile.txt'

'Get-Content | Measure-Object'
(measure-command {
Get-Content $testfile |
  Measure-Object -Line | select -expand Lines 
}).TotalSeconds
''

'StreamReader'
(measure-command {
$count=0
$reader = New-Object IO.StreamReader $testfile
while($reader.ReadLine() -ne $null){$count++}
$reader.close()
}).TotalSeconds
''

'Get-Content -ReadCount'
(measure-command {
$count=0
Get-Content $testfile -ReadCount 1000 |
  foreach {$count += $_.count}
}).TotalSeconds



Get-Content | Measure-Object
175.0600678

StreamReader
20.3832785

Get-Content -ReadCount
6.0199737

答案 1 :(得分:2)

我就是这样做的:

gci *.txt | % { 
    $lineCount = gc $_ | Measure-Object -Line | select -expand Lines
    select -InputObject $_ CreationTime, Name, @{Name="LineCount"; Expression={$lineCount}} 
    } | ConvertTo-Csv

从我的测试来看,文件上的gc似乎没有将整个文件加载到内存中(它必须使用一些流水线技术),所以可能没有必要编写自己的行计数器。 / p>

我在PS3中测试过。其中一个文本文件是13GB。

答案 2 :(得分:1)

这几乎是你在这里的所有代码...我在ForEach循环之外添加了$Output作为空数组。然后在循环内部,我使用您指定的值创建一个自定义对象,并将该对象添加到每个传递的数组中。最后,我在ForEach循环结束后使用Export-CSV将$Output保存到CSV文件中。

$fileEntries = [IO.Directory]::GetFiles("T:\frg\working"); 
$OutPut = @()
foreach($fileName in $fileEntries) 
{ 
    $count = 0
    $filedate = (Get-Date).Date
    $reader = New-Object IO.StreamReader $filename
    while($reader.ReadLine() -ne $null){$count++}
    $reader.close()
    #Get-Content $filename | %{$lines++}
    [Console]::Writeline($filename+" "+$count+" "+ $filedate);
    $Current = New-Object -TypeName PSObject -Property @{
        FileName = $filename
        Count = $count
        FileDate = $filedate
    }
    $Output += $Current
}
$Output|Export-CSV C:\SomeFile.csv -notypeinfo