Reputation: 447
Say I've got a list of items. I'd like to export to csv, but I want to do some calculations / modifications before I do so.
Basically, the setup looks like this:
PS C:\Files> gci
Directory: C:\Files
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 10/23/2014 6:03 PM 11084 Blob.txt
-a--- 10/13/2014 1:32 PM 31591 dates.txt
-a--- 2/11/2014 1:46 PM 11990 out.txt
PS C:\Files> $data = gci
And I can select the items I want to put into CSV easily enough. The actual Export-CSV part is omitted for brevity
PS C:\Files> $data | Select-Object FullName,name
But what I REALLY want to do is calculate a few columns and also include those in the CSV. Just as an example, say I want to count the '\' characters to get an idea of the folder depth. I think you can tell what I am trying here, even though it errors out.
PS C:\Files> $data | Select-Object FullName,name,FullName.Split('\').Count
Select-Object : A positional parameter cannot be found that accepts argument '1'.
Is there a way to get this to work?
Upvotes: 13
Views: 15689
Reputation: 36297
What you need is a calculated property (thank you Ansgar Wiechers for correcting my terminology and providing a link) to do that for you. You can accomplish this in a Select command by creating a kind of impromptu hashtable like so:
PS C:\Files> $data | Select-Object FullName,name,@{name='FolderDepth';expression= {$_.FullName.Split('\').Count}}
That could be shortened to @{n='Name';e={scriptblock}}
where n
stands for name, and is interchangeable with l
(short for label). e
is short for expression.
Upvotes: 21
Reputation: 46710
Yes. What you are looking for is more complex Select-Object
statement using calculated property. Sample syntax:
@{Label = "Calculation";Expression ={$_.FullName.Split('\').Count}}
Then you insert this into a select statement, usually with other variables.
$data | Select-Object FullName,name,@{Label = "TheCount";Expression ={$_.FullName.Split('\').Count}}
Upvotes: 3
Reputation: 5861
My Proposal (also a bit more readable then doing it in select):
$data | % {Add-Member -name FolderDepth -Value $_.FullName.split("\").Count -MemberType NoteProperty -InputObject $_} | select FullName,Name,FolderDepth
This adds a Property to $data which you can use further in the Pipeline with $_.FolderDepth
just like any other property.
What makes this different is this property will also be available after the pipeline if you want to do stuff with it afterwards
Upvotes: 0