Как сделать математическую операцию для нескольких файлов CSV - PullRequest
0 голосов
/ 04 марта 2020

Я нашел этот код:

$csv = Import-Csv D:\ExcelFiles\ba.csv
$csvout = "D:\ExcelFiles\bas.csv"

$csv | ForEach-Object {
    # Do the math
    $_.result = [math]::round($_.A / $_.B, 0)
    # Output the object (which contains A, B and result)
    $_
} | Export-Csv $csvout -NoTypeInformation

Как вы можете видеть, это только для импортированного файла CSV. Как сделать эту операцию для нескольких файлов CSV?

Edit1:

Я использовал этот код:

$SourcePath = "D:\CsvFiles"

$CsvFiles = Get-ChildItem -Path $SourcePath -filter "*.csv"

foreach ($File in $CsvFiles)
{
 $OutFile = "D:\CsvFiles\" + "\" + $File.BaseName + "s" + $File.Extension

$File | ForEach-Object 
{

            $_.result = [math]::round($_.A / $_.B, 0)
            # Output the object (which contains A, B and result)
            $_
        } | Export-Csv $OutFile -NoTypeInformation
}

Но он спрашивает:

cmdlet ForEach-Object at command pipeline position 1

Supply values for the following parameters:

Чтобы предотвратить это, я изменил код, как показано ниже (положение скобок после объекта foreach):

$SourcePath = "D:\CsvFiles"

$CsvFiles = Get-ChildItem -Path $SourcePath -filter "*.csv"

foreach ($File in $CsvFiles)
{
 $OutFile = "D:\CsvFiles\" + "\" + $File.BaseName + "s" + $File.Extension

$File | ForEach-Object {

            $_.result = [math]::round($_.A / B, 0)
            # Output the object (which contains A, B and result)
            $_
        } | Export-Csv $OutFile -NoTypeInformation
}

На этот раз я получил эту ошибку:

Свойство ' результат 'не может быть найден на этом объекте. Убедитесь, что свойство существует и может быть установлено.

Спасибо.

Ответы [ 2 ]

0 голосов
/ 05 марта 2020

Прежде всего, Get-ChildItem возвращает объекты FileInfo и / или DirectoryInfo, поэтому я бы посоветовал добавить к нему переключатель -File, чтобы вы знали, что имеете дело только с файлами.

Затем вы перебираете эти файлы и в этом l oop вы делаете что-то очень странное, а именно $File | ForEach-Object. Переменная $File здесь содержит один объект FileInfo, а не импортированные данные этого файла.

Вопрос не говорит о том, все ли файлы имеют столбец с именем result, поэтому код должен проверить это и, наконец, помнить, что все, что вы импортируете из CSV, это строка . Для этого нужно преобразовать в тип данных цифр c. Код ниже использует простое приведение к [double] для этого.

$SourcePath = "D:\CsvFiles"
$CsvFiles   = Get-ChildItem -Path $SourcePath -Filter "*.csv" -File

$CsvFiles | ForEach-Object {
    # create an output filepath. Since you are filtering on '*.csv', we can hardcode the extension here
    $OutFile = Join-Path -Path $SourcePath -ChildPath ('{0}s.csv' -f $_.BaseName)

    # so you know what file you are creating
    Write-Host "Working on $OutFile" -ForegroundColor Yellow

    # import the data from the file ($_) and calculate
    Import-Csv -Path $_.FullName | ForEach-Object {
        # since you're doing math, the values in A and B need to be converted from string to numeric type
        $result = [Math]::Round([double]$_.A / [double]$_.B, 0)
        # if the csv does not contain a column 'result', create it
        if ($_.PSObject.Properties.Name -notcontains 'result') { 
            $_ | Add-Member -MemberType NoteProperty -Name 'result' -Value $result 
        }
        else {
            $_.result = $result
        }
        # Output the object (which contains A, B and result)
        $_
    } | Export-Csv -Path $OutFile -NoTypeInformation
}
0 голосов
/ 04 марта 2020

Предполагая, что все файлы находятся в одном и том же каталоге, остальное в приведенном выше примере равно точно :

$Directory = "D:\CSVFiles"

$Files = Get-ChildItem -Path $Directory

foreach ($File in $Files)
{
    $OutFile = $Directory + "\" + $File.BaseName + "s" + $File.Extension

    $File | ForEach-Object
        {
            $_.result = [math]::round($_.A / $_.B, 0)
            # Output the object (which contains A, B and result)
            $_
        } | Export-Csv $OutFile -NoTypeInformation
}

Конечно, без примеров файлов это невозможно проверить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...