Home > Software design >  Powershell - use CSV to create multiple text files
Powershell - use CSV to create multiple text files

Time:08-24

I am trying to create a PS script that autogenerates txt files using a CSV file as an input.

The CSV file contains data such as this:

Category Product Priced
Bike Red bike Yes
Bike Blue bike Yes
Bike Black bike No
Car Red car No
Car Blue car Yes

The script should get a CSV as an input and generate 2 txt files (because we have 2 categories):

Example:

txt file 1: Bike.txt

Red bike - Yes
Blue bike - Yes
Black bike - No

I tried using this code, but it does not act the way I want it to:

$csv = Import-CSV -Path path.csv -Delimiter ";"

foreach($record in $csv){

    $cat_array  = $record.Category

    foreach($Product in $cat_array){
        .....
    }
}

I think I am handling the logic wrong.

CodePudding user response:

Here is a possible solution:

# Group CSV data by column Category and loop over groups
Import-CSV -Path path.csv -Delimiter ";" | Group-Object Category | ForEach-Object {

    # Create a text file from the current group
    $fileName = "$($_.Name).txt"
    Set-Content $fileName -Value "$($_.Name) file contains:"

    # Loop over the rows of the CSV and add the data to the txt file
    $_.Group | ForEach-Object {
        # Format one line of the current text file
        ($_.Product, $_.Priced) -join ' - '
    } | Add-Content $fileName
}

Output:

Bike.txt

Red bike - Yes
Blue bike - Yes
Black bike - No

Car.txt

Red car - No
Blue car - Yes

Detailed explanation:

The Group-Object command groups data by specified criteria, in this case the value of property (column) Category. To better understand how it works, it helps to remove the ForEach-Object command:

Import-CSV -Path path.csv -Delimiter ";" | Group-Object Category

This outputs:

Count Name Group
----- ---- -----
    3 Bike {@{Category=Bike; Product=Red bike; Priced=Yes}, @{Category=Bike; Product=Blue bike; Priced=Yes}, @{Category=Bike;…
    2 Car  {@{Category=Car; Product=Red car; Priced=No}, @{Category=Car; Product=Blue car; Priced=Yes}}

So for each group (Bike, Car), it outputs one object, which has the properties Count (number of grouped objects), Name (value of property by which it groups) and Group (an array of grouped objects).

So when iterating over the output of Group-Object, the ForEach-Object script block gets called one time per group. At this level the file will be created.

We then iterate over the elements of the Group array, which contains the rows of the CSV for the current category, to create the lines of the file, using the -join operator to format each line. This ends up in the file because it is implicit output, piped to the next command.

Finally output the file by piping to Set-Content. If necessary, use the -Encoding parameter to specify a non-default encoding (PS 5.x defaults to ANSI, while PS 7.x defaults to UTF-8).

  • Related