Question:
I get the below output from a PowerShell query. I don’t have access to the server to run the query, so I have no option to influence the output format.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 |
Name : folderC FullName : D:\folderA\folderB\folderC Length : CreationTime : 2/8/2014 11:12:58 AM LastAccessTime: 2/8/2014 11:12:58 AM Name : filename.txt FullName : D:\folderA\folderB\filename.txt Length : 71560192 CreationTime : 11/25/2015 3:10:43 PM LastAccessTime: 11/25/2015 3:10:43 PM |
How can I format above content to get something more usable, maybe like a table format like so:
1 2 |
Name|FullName|Length|CreationTime|LastAccessTime |
Answer:
As @alroc notes in a comment on the question, it is possible that objects are available to the OP, given that they state that the output is “from a Powershell query” – if so, simple reformatting of the object array using the usual cmdlets is an option.
By contrast, this answer assumes that only a text representation, as printed in the question, is available.
Dave Sexton’s answer is a simpler and more elegant choice, if:
- the input has no empty values (the OP’s sample input does).
- the input file is small enough to be read into memory as a whole.
Consider the approach below to avoid the issues above and/or if you want more control over how the input is converted into custom objects, notably with respect to creating properties with types other than [string]
: extend the toObj()
function below (as written, all properties are also just strings).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
Get-Content File | % ` -begin { function toObj([string[]] $lines) { $keysAndValues = $lines -split '(?<=^[^ :]+)\s*: ' $htProps = @{} for ($i = 0; $i -lt $keysAndValues.Count; $i += 2) { $htProps.($keysAndValues[$i]) = $keysAndValues[$i+1] } return [PSCustomObject] $htProps } $lines = @() } ` -process { if ($_.trim() -ne '') { $lines += $_ } else { if ($lines) { toObj $lines } $lines = @() } } ` -end { if ($lines) { toObj $lines } } | Format-Table |
Explanation:
- Uses
ForEach-Object
(%
) with separatebegin
,process
, andend
blocks. - The
-begin
, executed once at the beginning:- Defines helper function
toObj()
that converts a block of contiguous nonempty input lines to a single custom object.toObj()
splits an array of lines into an array of contiguous key-value elements, converts that array to a hashtable, which is then converted to a custom object.
- Initializes array
$lines
, which will store the lines of a single block of contiguous nonempty input lines
- Defines helper function
- The
-process
block, executed for each input line:- If the input line at hand is nonempty: Adds it to the current block of contiguous nonempty input lines stored in array
$lines
. - Otherwise: Submits the current block to
toObj()
for conversion to a custom object, and then resets the$lines
array to start the next block. In effect,toObj()
is invoked for each paragraph (run of nonempty lines).
- If the input line at hand is nonempty: Adds it to the current block of contiguous nonempty input lines stored in array
- The
-end
block, executed once at the end:- Submits the last paragraph to
toObj()
for conversion to a custom object.
- Submits the last paragraph to
- Finally, the resulting array of custom objects is passed to
Format-Table
.