Возьмите строку из одного csv-файла и разделите ее на столбцы для другого csv-файла с помощью powershell

#powershell #csv

#powershell #csv

Вопрос:

У меня есть файл csv, содержащий строки, которые я хотел бы извлечь и добавить в виде столбцов в отдельный файл csv.

Это пример содержимого первого csv-файла.

введите описание изображения здесь

Я хочу взять все между третьей запятой и точкой с запятой для каждого и добавить их в качестве столбцов в этот csv-файл.

введите описание изображения здесь

Мой желаемый результат таков. Поскольку в первом csv-файле может быть несколько серверов, я хотел бы экспортировать csv для каждого сервера, но я могу разобраться с этим.

введите описание изображения здесь

Я играл со следующим, но я не могу понять это.

 Import-CSV $CsvTargetPath | ForEach-Object {
$newData = $_

Import-CSV $CsvSourcePath | ForEach-Object {
    $_.AdditionalDisks.split(";") | ForEach-Object {
        $newRecordProperties = [ordered]@{
            $DriveLetter = $_.split(",")[3]
            $Label = $_.split(",")[4]
            $Filesystem = $_.split(",")[5]   
        }
        $newRecord = new-object psobject -Property $newRecordProperties
        Write-Output $newRecord
    }

    $CsvTargetPath | Add-Member -MemberType NoteProperty -Name DriveLetter -Value $DriveLetter -PassThru
    $CsvTargetPath | Add-Member -MemberType NoteProperty -Name Label -Value $Label -PassThru
    $CsvTargetPath | Add-Member -MemberType NoteProperty -Name Filesystem -Value $Filesystem -PassThru
}      
} | Export-CSV $CsvTargetPath -NoTypeInformation
  

Вот содержимое первого csv-файла в виде обычного текста.

 VmName  AdditionalDisks
Server01    90,0,thick,b,sql backup,refs;110,1,thick,d,sql data,refs;60,2,thick,f,sql transaction log,refs;50,3,thin,l,sql audit,refs;30,0,thick,t,sql tempdb data,refs
Server02    90,0,thick,b,sql backup,refs;110,1,thick,d,sql data,refs;60,2,thick,f,sql transaction log,refs;50,3,thin,l,sql audit,refs;30,0,thick,t,sql tempdb data,refs
  

Комментарии:

1. Пожалуйста, не могли бы вы отредактировать свой вопрос и показать нам первые 3 или 4 строки (по крайней мере) первого CSV-файла в виде обычного текста (скопировать из блокнота), чтобы нам не приходилось вводить то, что у вас уже есть?

Ответ №1:

Предполагая, что второй csv-файл также может содержать информацию для нескольких серверов (как еще вы могли бы узнать Uuid для каждого диска?), Вы могли бы сделать, как показано ниже

 $additionalDiskInfo = Import-Csv -Path 'D:Testfile1.csv'
$serverInfo         = Import-Csv -Path 'D:Testfile2.csv'

$additionalDiskInfo | ForEach-Object {
    $server      = $_.VmName
    $targetItems = $serverInfo | Where-Object { $_.VmName -eq $server }
    $extraDisks  = $_.AdditionalDisks -split ';'
    # make sure you don't run into index errors
    $maxItems = [math]::Min($targetItems.Count, $extraDisks.Count)
    # loop through the arrays and output combined objects
    $result = for ($i = 0; $i -lt $maxItems; $i  ) {
        $n1, $n2, $n3, $driveLetter, $label, $fileSystem = $extraDisks[$i] -split ','
        $targetItems[$i] | Select-Object *, 
                                         @{Name = 'DriveLetter'; Expression = {$driveLetter}},
                                         @{Name = 'Label'; Expression = {$label}},
                                         @{Name = 'FileSystem'; Expression = {$fileSystem}}
    } 
    # now write a new csv file for this server
    $result | Export-Csv -Path ('D:TestDiskInfo-{0}.csv' -f $server) -NoTypeInformation
}
  

Результирующие csv-файлы будут выглядеть следующим образом

 "VMName","Harddisk","Uuid","DriveLetter","Label","FileSystem"
"Server01","Hard disk 2","600C293-7e48-3a63-fb02-cd44df98fe79","b","sql backup","refs"
"Server01","Hard disk 3","600C293-7e48-3a63-fb02-cd44df98f454","d","sql data","refs"
"Server01","Hard disk 4","600C293-7e48-3a63-fb02-cd44df98f10a","f","sql transaction log","refs"
"Server01","Hard disk 5","600C293-7e48-3a63-fb02-cd44df98f483","l","sql audit","refs"
"Server01","Hard disk 6","600C293-7e48-3a63-fb02-cd44df98fced","t","sql tempdb data","refs"

  

Ответ №2:

Попробуйте так:

 $csv=Import-Csv $CsvSourcePath
$csv|%{
[pscustomobject][ordered]@{
DriveLetter=($_.AdditionalDisks.Split(","))[3]
Label=($_.AdditionalDisks.Split(","))[4]
FileSystem=($_.AdditionalDisks.Split(","))[5]
}}|export-csv $CsvTargetPath -append