Powershell: Как добавить столбец в существующий CSV?

Я видел много случаев, когда люди пытались делать разные вещи с CSV в Powershell, я новичок в CSV и не видел, чтобы кто-нибудь пытался делать то же, что и я. Вот короткая версия: я написал сценарий, который собирает много информации о подпапках любого каталога, в котором находится PS1, и выводит имена папок и количество файлов в файл CSV.

Таким образом, столбец A содержит все имена папок, столбец B содержит количество файлов в каждой папке со значением Get-Date в качестве заголовка столбца; все, что я хочу сделать, это каждый раз, когда я запускаю сценарий, добавлять новый столбец данных со значением Get-Date в качестве заголовка столбца и количеством файлов для этого экземпляра сценария.

Проблема в том, что независимо от того, как я меняю команду Export-CSV, либо ничего не происходит, либо я получаю странный результат, который не соответствует моим ожиданиям (например, в приведенном ниже примере кода, когда я запускаю его в первый раз). работает отлично, но когда я запускаю его во второй раз, он создает вторую серию строк ниже первой без каких-либо дополнительных данных).

Я знаю, что это должно быть до абсурда просто, но я, хоть убей, не могу понять, как это сделать. Могут ли люди здесь помочь мне? (И, пожалуйста... Я прочитал больше справочных статей, чем могу рассчитывать, обо всем, от добавления участника до присоединения, и не могу найти ответа, поэтому, если вы ответите, предоставьте пример кода, с которым я могу работать. с)

Код:

$sourceDir = $PSScriptRoot
$parentFolder = (Split-Path $sourceDir -Parent)
$thisDrive = (Split-Path -Path $sourceDir -Qualifier) + "\"
$columnDate = (Get-Date)

If ($sourceDir -eq $thisDrive)
    {
    $thisFolderName = "ROOT";
    } else {
    $thisFolderName = (Split-Path -Path $sourceDir -Leaf)
    }

$newFileName = "_Folder-Stats_" + $thisFolderName + "_AND_SUBFOLDERS_Ongoing.csv"
$outputFile = $sourceDir + $newFileName
$scriptName = $MyInvocation.MyCommand;
$thisScript = ($sourceDir + $scriptName)

Write-Host "OPERATION: Determine Folder Size and Quantify Contents (SOURCEDIR-ROOT Only) & Export CSV" -ForegroundColor White -BackgroundColor DarkGreen;
Write-Host "SOURCEDIR: " -NoNewline;
Write-Host "'$sourceDir'" -ForegroundColor Yellow;
Write-Host "THISDRIVE: " -NoNewline;
Write-Host "'$thisDrive'" -ForegroundColor Yellow;
Write-Host "THISFOLDERNAME: " -NoNewline;
Write-Host "'$thisFolderName'" -ForegroundColor Yellow;
Write-Host "OUTPUTFILE: " -NoNewline;
Write-Host "'$outputFile'" -ForegroundColor Yellow;

Write-Host " "
Write-Host "Beginning operation " -NoNewLine -ForegroundColor White
Write-Host "GET-CHILDITEM" -NoNewLine -ForegroundColor Yellow
Write-Host " on " -NoNewLine -ForegroundColor White
Write-Host "SOURCEDIR" -NoNewLine -ForegroundColor Yellow
Write-Host "..." -ForegroundColor White -NoNewLine

$rootFolders = (Get-ChildItem -LiteralPath $sourceDir -Directory)

Write-Host "operation complete." -ForegroundColor Green

$numFolders = ($rootFolders | Measure-Object ).Count;
$displayFolders = ('{0:N0}' -f $numFolders)

Write-Host " "
Write-Host "Total Folders Found:        " -NoNewLine -ForegroundColor White
Write-Host $displayFolders -ForegroundColor Yellow -NoNewLine
Write-Host " folders"
Write-Host " "

Write-Host "Beginning " -NoNewLine -ForegroundColor White
Write-Host "FOREACH" -NoNewLine -ForegroundColor Yellow
Write-Host " operation, please wait..." -ForegroundColor White
Write-Host " "
Write-Host "=========================================================== = " -ForegroundColor Green

$i = 0;
$folderSummary = foreach($thisFolder in $rootFolders.FullName) {
    $i += 1;
    $folderName = Split-Path $thisFolder -Leaf

    Write-Host "FOREACH: " -NoNewLine -ForegroundColor Green
    Write-Host "Folder $i of $displayFolders" -ForegroundColor Yellow
    Write-Host " "
    Write-Host "FOREACH:GET-CHILDITEM" -NoNewLine -ForegroundColor Green
    Write-Host " on folder " -NoNewLine -ForegroundColor White
    Write-Host $thisFolder -NoNewLine -ForegroundColor Yellow
    Write-Host "." -ForegroundColor White
    Write-Host "FOREACH:FOLDERNAME: " -NoNewLine -ForegroundColor Green
    Write-Host $folderName -ForegroundColor Yellow

    $contents = Get-ChildItem -LiteralPath $thisFolder -File -Force -Recurse

    $numFiles = ($contents | Measure-Object ).Count;
    $displayFiles = ('{0:N0}' -f $numFiles)

    $numBytes = ($contents | Measure-Object -Property Length -sum).sum
    $displayBytes = ('{0:N0}' -f $numBytes)

    Write-Host " "
    Write-Host "FOREACH:Total Files Found:      " -NoNewLine -ForegroundColor Green
    Write-Host $displayFiles -ForegroundColor Yellow -NoNewLine
    Write-Host " files." -ForegroundColor Green


    Write-Host "FOREACH: Total Bytes Found:     " -NoNewLine -ForegroundColor Green
    Write-Host $displayBytes -ForegroundColor Yellow -NoNewLine
    Write-Host " bytes." -ForegroundColor Green

    Write-Host " "
    Write-Host "FOREACH: Beginning operation " -NoNewLine -ForegroundColor White
    Write-Host "PSCUSTOMOBJECT" -NoNewLine -ForegroundColor Yellow
    Write-Host " on folder " -NoNewLine -ForegroundColor White
    Write-Host $thisFolder -NoNewLine -ForegroundColor Yellow
    Write-Host ", please wait..." -ForegroundColor White
    Write-Host " "

#   $childFiles = $contents | Where-Object {!($_.PsIsContainer)}

    Write-Host " "
    Write-Host "FOREACH.THISFOLDER: " -ForegroundColor Green -NoNewLine
    Write-Host $folderName -ForegroundColor Yellow
    Write-Host "FOREACH.THISFOLDER.FILECOUNT: " -ForegroundColor Green -NoNewLine
    Write-host $displayFiles  -ForegroundColor Yellow
    Write-Host "FOREACH.THISFOLDER.SIZE.BYTES: " -ForegroundColor Green -NoNewLine
    Write-Host $displayBytes  -ForegroundColor Yellow

#   PAUSE
    
    [PSCustomObject] @{
        'folderName' = $folderName
        $columnDate = $numFiles
    }
#Write-Host "=========================================================== = " -ForegroundColor Green
Write-Host " "
Write-Host "------------------------------------------------------------" -ForegroundColor Green
}
$folderSummary | Export-Csv $outputFile -Append -Force
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
76
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ничего особенного делать не нужно, кроме как импортировать CSV, добавить новую дату в качестве имени свойства, где это необходимо, а затем экспортировать ее.

Имейте соответствующие фрагменты кода, протестированные на 5.1 и 7.4.

# Get the pre-formatted date.  
$columnDate = Get-Date -Format 'yyyy/MM/dd'

# Import the existing CSV as a List.  
# I suggest specifying the delimeter character both here and in Export-Csv.  
if (Test-Path $outputFile) { [System.Collections.Generic.List[psobject]]$CsvContent = Import-Csv -LiteralPath $outputFile -Delimiter ',' }
# if the file doesn't exist or is empty, create a empty list.  
if ($null -eq $CsvContent) { $CsvContent = [System.Collections.Generic.List[psobject]]::new() }


foreach ($thisFolder in $rootFolders.FullName) {

    $folderName = Split-Path $thisFolder -Leaf

    $contents = Get-ChildItem -LiteralPath $thisFolder -File -Recurse -Force 

    $numFiles = ($contents | Measure-Object ).Count

    # check if there already is a line with the name of the current directory.  
    if ($CsvContent | Where-Object -Property folderName -EQ -Value $folderName) { 
        # get the index of the line.  
        $index = $CsvContent.FindIndex({ $folderName -eq $args[0].folderName })
        # if the line doesn't have a column with the current date as name, add it with the
        # number of files as value.  
        if (-not $CsvContent[$index].$columnDate) { 
            $CsvContent[$index] | Add-Member -MemberType NoteProperty -Name $columnDate -Value $numFiles 
        }
        # uncomment the following line if you want to update the values of the current day when
        # running the script.  
        # else { if ($numFiles -ne $CsvContent[$index].$columnDate) { $CsvContent[$index].$columnDate = $numFiles } }
    }
    # if there is no line with the current folder as name, add folder and date values.  
    else { 
        $CsvContent.add(
            [PSCustomObject] @{
                'folderName' = $folderName
                $columnDate  = $numFiles
            }
        )
    }

    
}
# export the list to CSV
$CsvContent | Export-Csv $outputFile -Force -NoTypeInformation -Delimiter ',' 

Другие вопросы по теме