【问题标题】:-split function doesn't work in a big file Powershell-split 函数在大文件 Powershell 中不起作用
【发布时间】:2020-02-27 23:12:34
【问题描述】:

我正在尝试使用 Powershell 解析 csv 文件,但拆分功能不起作用。我正在使用拆分和原始行比较文件输出。拆分仅适用于前几行。我不知道我是否遗漏了什么。这是我的代码

$table = Get-Content .\random.csv -ReadCount 1000

$fname_mid = 'ps.mid'
$fname_mif = 'ps.mif'

New-Item -Path . -Name $fname_mid -ItemType 'file' -Force
New-Item -Path . -Name $fname_mif -ItemType 'file' -Force

ForEach($_ In $table) 
{
    $read_field = $_ -split ','
    $read_line = '----' + $read_field[0] + ',-' + $read_field[9] + '-'

    $read_line | Out-File -Encoding 'UTF8' -FilePath $fname_mid -Append
    $_ | Out-File -Encoding 'UTF8' -FilePath $fname_mif -Append
}

测试文件https://www.dropbox.com/s/99zgerh2akemgy3/random.csv?dl=0

【问题讨论】:

  • this >>> ForEach($_ In $table) $_ 变量是 current pipeline item ...并且您没有使用该管道。将其替换为适当的当前项目变量 [也许是 $T_Item] 并看看会发生什么。
  • -ReadCount 指定一次通过管道发送多少内容。因此,$Table.Count => 40 和$Table[0].Gettype() => Object[]($Table[0] -split [System.Environment]::NewLine).Count => 1000 和 ($Table[-1] -split [System.Environment]::NewLine).Count => 233。
  • 你为什么不使用 Import-csv?如果是普通的 csv,这将是简单的方法。
  • @WalterMitty 因为文件大小大于 10MB 时速度很慢
  • 当您通过管道提供其输出时,它的工作速度会更快。

标签: powershell csv split


【解决方案1】:

在您的问题中提出的问题(也由 cmets 列出):

  • 来自@Lee_Dailey:
    这 >>> ForEach($_ In $table) 当前管道项 ...并且您没有使用管道。将其替换为适当的当前项目变量 [也许是 $T_Item] 并看看会发生什么。
  • 来自@JosefZ:
    -ReadCount 指定一次通过管道发送多少行内容。因此,
    $Table.Count => 40 和 $Table[0].Gettype() => Object[]
    ($Table[0] -split [System.Environment]::NewLine).Count => 1000 和
    ($Table[-1] -split [System.Environment]::NewLine).Count => 233
  • 在提供的示例中,您有 9 列,这意味着最后一项是
    $read_field[8] (8不是9)
  • 这个声明 $_ | Out-File -Encoding 'UTF8' -FilePath $fname_mif -Append 没有多大作用(除非您的来源不是 UTF8,但还有其他方法可以实现相同的目的)
  • 您想如何处理输入文件中的引号?

你会得到类似的东西:

$table = Get-Content .\random.csv

$fname_mid = 'ps.mid'
$fname_mif = 'ps.mif'

New-Item -Path . -Name $fname_mid -ItemType 'file' -Force
New-Item -Path . -Name $fname_mif -ItemType 'file' -Force

ForEach($Line In $table) 
{
    $read_field = $Line -split ','
    $read_line = '----' + $read_field[0] + ',-' + $read_field[8] + '-'

    $read_line | Out-File -Encoding 'UTF8' -FilePath $fname_mid -Append
    # $Line | Out-File -Encoding 'UTF8' -FilePath $fname_mif -Append
}

但是您低估了Import-csv(由@Walter Mitty 评论)的性能(和易用性)以及它附带的复杂的PowerShell 管道。关键是,如果您想将其与为流式传输而构建的 cmdlet 进行比较,则不能仅将 性能测量基于单个命令。在这种情况下,您需要测量完整的解决方案

您的(更正后的)示例耗时超过 7 分钟
流式传输将花费不到 3 秒

Import-Csv .\random.csv -Head (0..8) | 
ForEach-Object {"----$($_.0),-$($_.8)-"} | 
Set-Content .\fname_mid

【讨论】:

  • 感谢您在回答中引用我的评论。我认为这是要走的路,但我懒得构建一个使用 import-csv 的答案。
  • 我是 Powershell 新手,它帮助我了解了 PS 的工作原理,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-20
  • 2013-03-22
  • 1970-01-01
相关资源
最近更新 更多