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).