【问题标题】:Count records in csv file - Powershell计算 csv 文件中的记录 - Powershell
【发布时间】:2015-08-29 01:07:33
【问题描述】:

我有以下 PS 脚本来计数。有没有办法在不导入整个 csv 的情况下计算(减去标题)?有时 csv 文件很大,有时没有记录。

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

【问题讨论】:

    标签: powershell csv


    【解决方案1】:

    要计算行数而不用担心标题,请使用:

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

    但是,这必须将整个文件读入内存。一种更快的计算文件的方法是使用带有 readcount 标志的 Get-Content,如下所示:

    $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]
    

    【讨论】:

      【解决方案2】:

      这是检查 CSV 文件是否为空的函数(如果为空则返回 True,否则返回 False),具有以下功能:

      • 可以跳过标题
      • 在 PS 2.0 中工作(PS 2.0 没有 -ReadCount 切换 Get-Content cmdlet)
      • 不在内存中加载整个文件
      • 了解 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
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2011-10-14
        • 1970-01-01
        • 1970-01-01
        • 2019-07-21
        • 1970-01-01
        • 2018-04-14
        • 1970-01-01
        • 2021-10-10
        • 2019-01-31
        相关资源
        最近更新 更多