如何将当前项目返回到管道? [英] How to return current item back to the pipeline?

查看:48
本文介绍了如何将当前项目返回到管道?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在导入 csv 文件并批量加载到 sql 表.

Im currently importing csv files and bulk loading to sql table.

使用此代码

$CSVDataTable = Import-Csv $csvFile | % -begin {$i=0} -process { Write-Progress -activity "Importing file" -currentOperation "Reading line $i" -PercentComplete -1; $i++; return $_ } | Out-DataTable

我能够显示进度,但我想对其进行优化,我发现的一项建议是使用 StreamReader.

i am able to show the progress, but I'd like to optimize it and one recommendation Ive found is utilizing StreamReader.

所以我尝试了以下方法:

so ive tried the following:

[int]$LinesInFile = 0
$reader = New-Object IO.StreamReader $csvFile
$line = $reader.ReadLine()
while($reader.ReadLine() -ne $null) { $LinesInFile++ }

$CSVDataTable = 0..($LinesInFile-1) | foreach {
    $percent = ($_/$LinesInFile)*100
    Write-Progress -Activity 'Importing from CSV' -Status "$percent % Complete" -CurrentOperation "Importing row # $($_+1)" -PercentComplete $percent;
    return $reader[$_]
} | Import-Csv $csvFile | Out-DataTable

错误(由于return $reader[$_]):

Import-Csv : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its
properties do not match any of the parameters that take pipeline input.

推荐答案

唯一有意义的管道到 Import-CsvSystem.IO.FileInfo 实例表示 CSV 文件,例如 Get-ChildItem 的输出(顺便说一句,由于 Windows PowerShell 中的错误而损坏,因为已在 PowerShell [Core] v6+ 中修复)).

The only thing that makes sense to pipe to Import-Csv are System.IO.FileInfo instances representing CSV files, such as output by Get-ChildItem (which, as an aside, is broken due to a bug in Windows PowerShell, since fixed in PowerShell [Core] v6+).

如果您想报告 Import-Csv 调用的进度,请将 ForEach-Object 命令放在之后,其中您可以发出进度消息,然后通过以下方式传递 Import-Csv 的输出对象 ($_):

If you want to report on the progress of an Import-Csv call, put a ForEach-Object command after it, in which you can emit the progress message and then pass Import-Csv's output object ($_) through:

# Count the data rows in the input CSV file.
$rowCount = 0
switch -File $csvFile { default { ++$rowCount } }
--$rowCount # subtract 1 from the line count to account for the header row.

Import-Csv $csvFile | ForEach-Object -Begin { $i = 0 } {

  $percent = '{0:N1}' -f (++$i / $rowCount * 100)
  Write-Progress -Activity 'Importing from CSV' -Status "$percent % Complete" -CurrentOperation "Importing row # $i" -PercentComplete $percent

  $_  # pass the object from Import-Csv through.

} | Out-DataTable

# Hide the progress bar now.
# (Otherwise it would linger until the script as a whole completes.)
Write-Progress '(unused))' -Completed


值得注意的是,每个对象 Write-Progress 调用会显着减慢执行速度(并且预先计算行数也有其成本,即使只是通过 ForEach-Object 调用传递对象).


It's worth noting that per-object Write-Progress calls significantly slow down execution (and counting the number of lines up front has its cost too, as does even just passing objects through via a ForEach-Object call).

缓解速度缓慢的一种简单方法是仅对每 N 个对象使用 Write-Progress,例如每个 100 个对象在下面的例子:

A simple way to mitigate the slowdown is to only use Write-Progress for every N objects, such as every 100 objects in the following example:

# Count the data rows in the input CSV file.
$rowCount = 0
switch -File $csvFile { default { ++$rowCount } }
--$rowCount # subtract 1 from the line count to account for the header row.

Import-Csv $csvFile | ForEach-Object -Begin { $i = 0 } {

  if (++$i % 100 -eq 1 -or $i -eq $rowCount) {
    $percent = '{0:N1}' -f ($i / $rowCount * 100)
    Write-Progress -Activity 'Importing from CSV' -Status "$percent % Complete" -CurrentOperation "Importing row # $i" -PercentComplete $percent
  }

  $_  # pass the object from Import-Csv through.

} | Out-DataTable

# Hide the progress bar now.
# (Otherwise it would linger until the script as a whole completes.)
Write-Progress '(unused))' -Completed

注意:如果 Out-DataTable 在将最后一个对象传递给它后需要大量的处理时间,您可以填充行数以基于百分比显示估计额外的时间,作为真实行数的百分比.

Note: If Out-DataTable requires a nontrivial amount of processing time after the last object has been passed to it, you could pad the number of rows for the purpose of the percentage display based on an estimate of that additional time, as a percentage of the true row count.

这篇关于如何将当前项目返回到管道?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆