Разделить содержимое из одного .csv на несколько файлов на основе содержимого с помощью powershell

У меня есть файл .csv с двумя типами строк. Первый содержит информацию заголовка. Он всегда начинается с AB. Второй тип содержит контент. Этот всегда начинается с CD. После каждой строки заголовка может быть несколько строк содержимого (всегда хотя бы одна). Они принадлежат друг другу до следующей строки заголовка (снова начиная с AB).

Пример:

header1; header2; header3; header4; header5; header6; header7
AB; 12345; AB123456789; 10.03.2021; GT; BC987654321; EUR
CD; 456789; 22.24; Text; SW;
AB; 12345; AB123456789; 10.03.2021; GT; BC987654322; EUR
CD; 354345; 85.45; Text; SW;
CD; 123556; 94.63; Text; SW;
CD; 354564; 12.34; Text; SW;
CD; 135344; 32.23; Text; SW;
AB; 12345; AB123456789; 10.03.2021; GT; BC987654323; EUR
CD; 354564; 12.34; Text; SW;
CD; 852143; 34.97; Text; SW;

Как я могу разделить этот файл на несколько .csv-файлов — по одному для каждой строки заголовка (AB) — с помощью PowerShell. Мой желаемый результат был бы

BC987654321.csv

header1; header2; header3; header4; header5; header6; header7
AB; 12345; AB123456789; 10.03.2021; GT; BC987654321; EUR
CD; 456789; 22.24; Text; SW;

BC987654322.csv

header1; header2; header3; header4; header5; header6; header7
AB; 12345; AB123456789; 10.03.2021; GT; BC987654322; EUR
CD; 354345; 85.45; Text; SW;
CD; 123556; 94.63; Text; SW;
CD; 354564; 12.34; Text; SW;
CD; 135344; 32.23; Text; SW;

и BC987654323.csv

header1; header2; header3; header4; header5; header6; header7
AB; 12345; AB123456789; 10.03.2021; GT; BC987654323; EUR
CD; 354564; 12.34; Text; SW;
CD; 852143; 34.97; Text; SW;

Я вообще не привык к PowerShell, поэтому буду признателен за удобное для новичков решение.

Заранее большое спасибо.


person Nerevar.de    schedule 10.03.2021    source источник
comment
Можете ли вы показать нам, что вы пробовали?   -  person Abraham Zinala    schedule 10.03.2021
comment
Это реальный пример вашего файла CSV? Где данные и почему мы видим только заголовки? Каков ваш желаемый результат?   -  person Theo    schedule 10.03.2021
comment
@Theo Это были не заголовки, а просто случайно выбранные имена ячеек. Я только что отредактировал вопрос, поэтому теперь пример больше похож на реальный файл.   -  person Nerevar.de    schedule 10.03.2021
comment
@AbrahamZinala В настоящее время я читаю, как PowerShell работает в целом, как я уже упоминал в вопросе, у меня пока нет буквально нулевого опыта в его использовании. По крайней мере, я смог добавить заголовок к файлу (в предоставленном файле его нет), поэтому с этого момента может быть проще работать с столбцами.   -  person Nerevar.de    schedule 10.03.2021


Ответы (1)


Если я правильно понимаю, вы хотите разделить csv на каждую строку, где «header1» равен «AB», а затем использовать то, что находится в этой строке под «header6» для имени выходного файла.

$path = 'D:\Test'
$fileIn = Join-Path -Path $path -ChildPath 'input.csv'
$fileOut = $null   # will get a value in the loop
$splitValue = 'AB' # the header1 value that decides to start a new file
$csv = Import-Csv -Path $fileIn -Delimiter ';'
# get an array of the column headers
$allHeaders = $csv[0].PsObject.Properties.Name
foreach ($item in $csv) {
    if ($item.header1 -eq $splitValue) { 
        # start a new file
        $fileOut = Join-Path -Path $path -ChildPath ('{0}.csv' -f $item.header6)
        # create the new csv file with the first row of data already in it
        $item | Select-Object $allHeaders | Export-Csv -Path $fileOut -Delimiter ';' -NoTypeInformation
    }
    else {
        # rows with header1 not 'AB' are added to that file
        if ([string]::IsNullOrEmpty($fileOut)) {
            Write-Warning "Could not find a starting row (header1 = '$splitValue') for the file"
        }
        else {
            $item | Select-Object $allHeaders | Export-Csv -Path $fileOut -Delimiter ';' -Append
        }
    }
}

Конечно, измените пути, чтобы они соответствовали вашей среде.

Выход:

BC987654321.csv

"header1";"header2";"header3";"header4";"header5";"header6";"header7"
"AB";"12345";"AB123456789";"10.03.2021";"GT";"BC987654321";"EUR"
"CD";"456789";"22.24";"Text";"SW";"";

BC987654322.csv

"header1";"header2";"header3";"header4";"header5";"header6";"header7"
"AB";"12345";"AB123456789";"10.03.2021";"GT";"BC987654322";"EUR"
"CD";"354345";"85.45";"Text";"SW";"";
"CD";"123556";"94.63";"Text";"SW";"";
"CD";"354564";"12.34";"Text";"SW";"";
"CD";"135344";"32.23";"Text";"SW";"";

BC987654323.csv

"header1";"header2";"header3";"header4";"header5";"header6";"header7"
"AB";"12345";"AB123456789";"10.03.2021";"GT";"BC987654323";"EUR"
"CD";"354564";"12.34";"Text";"SW";"";
"CD";"852143";"34.97";"Text";"SW";;
person Theo    schedule 10.03.2021
comment
Я получаю сообщение об ошибке $item | Export-Csv -Path $fileOut -Delimiter ';' -Append о том, что путь равен NULL или пуст. - person Nerevar.de; 10.03.2021
comment
@Nerevar.de нет, это означает, что не было начальной строки, в которой заголовок1 содержал значение AB. У меня есть только ваш пример, в реальной жизни вам нужно изменить AB на то, что действительно делает первую строку в файле для разделения. Я обновил свой ответ, так что теперь он покажет сообщение об этом и добавил новую переменную $splitValue, чтобы вы могли просто установить ее на то, что находится в реальном файле. - person Theo; 10.03.2021
comment
Да, я получил это. Я также изменил это до вашего обновления. Но даже ваше решение с новой переменной имеет тот же эффект. С вашим отредактированным кодом теперь отображается предупреждение вместо сообщений об ошибках. Даже пытался изменить содержимое файла на AB, чтобы проверить его с другой стороны. - person Nerevar.de; 10.03.2021
comment
@ Nerevar.de Тогда, пожалуйста, отредактируйте свой вопрос и покажите первые 3 или 4 строки файла, как они есть на самом деле. Использование примера работает. - person Theo; 10.03.2021
comment
Виноват. Мне не хватало изменить header1, который явно отличается и в реальных файлах. Я также создал последний вопрос о слиянии этих точных строк. stackoverflow.com/questions/66566801 Буду рад, если вы тоже это проверите. Спасибо еще раз! - person Nerevar.de; 10.03.2021