2015-08-28 87 views
0

我有以下PS腳本來計算。有沒有一種方法可以在不導入整個csv的情況下統計(減去標題)?有時候csv文件非常大,有時它沒有記錄。在csv文件計數記錄 - Powershell

Get-ChildItem 'C:\Temp\*.csv' | ForEach { 
    $check = Import-Csv $_ 
    If ($check) { Write-Host "$($_.FullName) contains data" } 
    Else { Write-Host "$($_.FullName) does not contain data" } 
} 

回答

1

計數行,而不用擔心頭使用這樣的:

$c = (Import-Csv $_.FullName).count 

然而,這需要讀取整個文件到內存中。計數文件更快的方法是使用Get-內容與readcount標誌,像這樣:

$c = 0 
Get-Content $_.FullName -ReadCount 1000 | % {$c += $_.Length} 
$c -= 1 

要從計數刪除標題行,你只是減去1.如果沒有行唐」你的文件噸有一個頭,你可以避開他們零下1像這樣計算:有以下特點

$c = 0 
Get-Content $_.FullName -ReadCount 1000 | % {$c += $_.Length} 
$c -= @{$true = 0; $false = - 1}[$c -eq 0] 
0

這裏是將檢查的CSV文件中的空函數(返回True如果是空的,False否則):

  • 可以跳過標題
  • 工程在PS 2.0(PS 2.0有不-ReadCount開關Get-Content小命令)
  • 不在存儲器加載整個文件
  • 意識到CSV文件結構的(不會計數空/無效的行)。

它接受下列參數:

  • 文件名路徑CSV文件。
  • MaxLine從文件中讀取的最大行數。
  • NOHEADER如果沒有指定此開關,功能將跳過該文件的第一行

用例:

Test-IsCsvEmpty -FileName 'c:\foo.csv' -MaxLines 2 -NoHeader 

function Test-IsCsvEmpty 
{ 
    Param 
    (
     [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] 
     [string]$FileName, 

     [Parameter(ValueFromPipelineByPropertyName = $true)] 
     [ValidateRange(1, [int]::MaxValue)] 
     [int]$MaxLines = 2, 

     [Parameter(ValueFromPipelineByPropertyName = $true)] 
     [switch]$NoHeader 
    ) 

    Begin 
    { 
     # Setup regex for CSV parsing 
     $DQuotes = '"' 
     $Separator = ',' 
     # http://stackoverflow.com/questions/15927291/how-to-split-a-string-by-comma-ignoring-comma-in-double-quotes 
     $SplitRegex = "$Separator(?=(?:[^$DQuotes]|$DQuotes[^$DQuotes]*$DQuotes)*$)" 
    } 

    Process 
    { 
     # Open file in StreamReader 
     $InFile = New-Object -TypeName System.IO.StreamReader -ArgumentList $FileName -ErrorAction Stop 

     # Set inital values for Raw\Data lines count 
     $CsvRawLinesCount = 0 
     $CsvDataLinesCount = 0 

     # Loop over lines in file 
     while(($line = $InFile.ReadLine()) -ne $null) 
     { 
      # Increase Raw line counter 
      $CsvRawLinesCount++ 

      # Skip header, if requested 
      if(!$NoHeader -and ($CsvRawLinesCount -eq 1)) 
      { 
       continue 
      } 

      # Stop processing if MaxLines limit is reached 
      if($CsvRawLinesCount -gt $MaxLines) 
      { 
       break 
      } 

      # Try to parse line as CSV 
      if($line -match $SplitRegex) 
      { 
       # If success, increase CSV Data line counter 
       $CsvDataLinesCount++ 
      } 
     } 
    } 

    End 
    { 
     # Close file, dispose StreamReader 
     $InFile.Close() 
     $InFile.Dispose() 

     # Write result to the pipeline 
     if($CsvDataLinesCount -gt 0) 
     { 
      $false 
     } 
     else 
     { 
      $true 
     } 
    } 
}