¿Cómo devolver el artículo actual a la tubería?
Actualmente estoy importando archivos csv y carga masiva a la tabla sql.
usando este código
$CSVDataTable = Import-Csv $csvFile | % -begin {$i=0} -process { Write-Progress -activity "Importing file" -currentOperation "Reading line $i" -PercentComplete -1; $i++; return $_ } | Out-DataTable
Puedo mostrar el progreso, pero me gustaría optimizarlo y una recomendación que he encontrado es utilizar StreamReader.
así que he intentado lo siguiente:
[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
Error (debido a ):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.
Respuestas
Lo único que tiene sentido para canalizar Import-Csvson System.IO.FileInfoinstancias que representan archivos CSV , como la salida por Get-ChildItem(que, aparte, está rota debido a un error en Windows PowerShell, ya que se corrigió en PowerShell [Core] v6 +).
Si desea informar sobre el progreso de una Import-Csvllamada, coloque un ForEach-Objectcomando después , en el que puede emitir el mensaje de progreso y luego pasar Import-Csvel objeto de salida ( $_) a través de:
# 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
Vale la pena señalar que las Write-Progressllamadas por objeto ralentizan significativamente la ejecución (y contar el número de líneas por adelantado también tiene su costo, al igual que incluso pasar objetos a través de una ForEach-Objectllamada).
Una forma sencilla de mitigar la ralentización es usar solo Write-Progresspara cada N objetos , como todos los 100objetos del siguiente ejemplo:
# 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
Nota: Si Out-DataTablerequiere una cantidad no trivial de tiempo de procesamiento después de que se le haya pasado el último objeto, puede rellenar el número de filas con el propósito de mostrar el porcentaje en función de una estimación de ese tiempo adicional, como un porcentaje de la fila verdadera. contar.