I have a [simplified] CSV file with 3 properties. Sample (subset of real data):
Person,Amount,Category Joe,5,Coffee Mary,15,Gas John,25,Food John,10,Beer Mary,8,Juice
I have a [simplified] CSV file with 3 properties. Sample (subset of real data):
Person,Amount,Category Joe,5,Coffee Mary,15,Gas John,25,Food John,10,Beer Mary,8,Juice
Sorry, please ignore this [2nd] post (but not the original post above).
Not intended to be a reply to the above but as a separate post.
I recommend you work on formatting your code in a more readable format.
Also identify and note the 4 different syntax errors in the code above.
The -in operator would replace multiple -eq operators in this case as in:
# $data = Import-Csv .\filename.ext
#region
$data = @()
$data += [PSCustomObject]@{
Person = 'Joe'
Amount = 5
Category = 'Coffee'
}
$data += [PSCustomObject]@{
Person = 'Mary'
Amount = 15
Category = 'Gas'
}
$data += [PSCustomObject]@{
Person = 'John'
Amount = 25
Category = 'Food'
}
$data += [PSCustomObject]@{
Person = 'John'
Amount = 10
Category = 'Beer'
}
$data += [PSCustomObject]@{
Person = 'Mary'
Amount = 8
Category = 'Juice'
}
#endregion
$CategoryList = $data.Category # or $CategoryList = @('Coffee','Cheese')
$data | Foreach-object -Process {
[pscustomobject]@{
Person = $_.Person
Amount = $_.Amount
Category = $( If ($_.Category -in $CategoryList ) { 'drink-'+$_.Category } else { $_.Category } )
}
}
Many thanks Mr Boutros. The code shown was the result of a Copy-Paste directly from VSCode editor, which in its original form was neatly formatted. I don’t understand why this led to the left-justified result and the syntax error (the blank character in VSCode, it seems, shows as a centered dot.). My apologies for this. Secondly, I gave the sample data of just 5 lines to illustrate the nature of my question. But I still haven’t found a way to type line by line sample data without the extra space. In fact I just posted a question for this in the feedback forum. The main purpose of the code I submitted was to convert the values of all the 5 categories of property Category (as it originated from the source) from: (coffee,tea,soda,juice,beer) to (drink-coffee,drink-tea,drink-soda,drink-juice,drink-beer).
Thanks again for your reply.
Within the help of calculated property and regex.
$Category = @{
E = {
if($_.Category -match "tea|soda|beer|juice"){
"Drink " + $_.Category
}
else{
$_.Category
}
}
L = 'Category'
}
$data = Import-Csv | Select-Object -Property Amount,Person,$Category
@Ramon,
Kvprasoon’s solution is very good and I would go for that.
However, just for information, you don’t need all those -EQ True, because every expression inside the if condition is already evaluated as $true or $false.
For example:
PS C:\> @('blue','red').Contains('blue')
True
PS C:\> @('blue','red').Contains('black')
False
PS C:\>
Therefore, this gives the same result as your original code:
Category=If(($_.Category).Contains('coffee') -OR
($_.Category).Contains('tea') -OR
($_.Category).Contains('soda') -OR
($_.Category).Contains('beer') -OR
($_.Category).Contains('juice')) {
'drink-'+$_.Category}
else {$_.Category}
I don’t see how the original code can work, since .contains() is case sensitive. Anyway:
Import-Csv food.csv | Foreach {
[pscustomobject]@{
Amount = $_.Amount
Person = $_.Person
Category = if ($_.category -in 'coffee','tea','soda','beer','juice') {
'drink-' + $_.Category}
else {
$_.Category}
}
}
Amount Person Category
------ ------ --------
5 Joe drink-Coffee
15 Mary Gas
25 John Food
10 John drink-Beer
8 Mary drink-Juice
or:
if ($_.category -match 'coffee|tea|soda|beer|juice') {
or:
if ('coffee','tea','soda','beer','juice' -contains $_.category) {
You can actually use -eq (or -match or -like) with a list, and it will return the thing in the list from the 2nd arg and end up being true:
PS /Users/js> 'coffee','tea','soda','beer','juice' -eq 'coffee'
coffee
PS /Users/js> 'coffee','tea','soda','beer','juice' -eq 'coffee2'
PS /Users/js>
if ('coffee','tea','soda','beer','juice' -eq $_.category) {
Mr Kvprasoon,
Your suggestion is very neat! I’m highly grateful for your solution.
Much thanks.
Many thanks Mr Fullenwarth,
Your examples are very useful and educational to me.
Best,
Yes JS is right: the Contains method is case sentitive.
And in addition, it must also match the whole element.
PS C:\> @('blue','red').Contains('blue')
True
PS C:\> #Case sensitive
@('blue','red').Contains('BLUE')
False
PS C:\> #Does not match the whole element
@('blue','red').Contains('blu')
False
PS C:\>
Note, VSCode, does include some random stuff that messes up copy / paste for forums and Q&A sites like this.
So, sure format in VSCode, but copy to notepad and check before you submit / post, otherwise use GitHub, paste in, etc… to link to your code.
This sites’, formatting code tags are what you should use when posting, and VSCode, the ISE and other tools do not do this automatically for obvious reasons. Meaning various sites, can and will have different formatting requirements.
Create yourself the necessary shortcuts in VSCode to use the formatting tags required by the sites you post to.
My sincerest gratitude to you all - Messrs. KVprasoon, Fullenwarth, Boutros, JS, Postanote.
I am very thankful that besides giving me excellent answers/solutions, you have also shared many interesting aspects of Powershell and provided numerous insights. Best,