I am having trouble manipulating the data returned from a PowerShell query.
My goal is to get all NAMEs that are great than 30 days old (>30d).
After that, I want to load the NAMEs of these results into an array.
The data returned from my query is as follows:
PS C:\Users\> $output
NAME STATUS AGE
dread-gorge Active 284d
dread-lagoon Active 210d
carncier-basin Active 164d
chantague-shallows Active 164d
hilraine-loch Active 311d
stangrave-waters Active 271d
Running a 'Select-Object' or 'Sort-Object' to filter the output doesn't work.
$output | Select-Object -Property NAME
$output | Sort-Object NAME
CodePudding user response:
If $output
is a single multiline string, you can do this:
$result = ($output -split '\r?\n' -replace '\s ', ',' | ConvertFrom-Csv | Where-Object {[int]($_.Age -replace '\D') -gt 30}).NAME
to get the Names in an array $result
.
If $output
is already an array of strings, do:
$result = ($output -replace '\s ', ',' | ConvertFrom-Csv | Where-Object {[int]($_.Age -replace '\D') -gt 30}).NAME
CodePudding user response:
Update:
For a superior solution that transforms the input into CSV format and parses it with
ConvertFrom-Csv
, see Theo's answer.The solution below may be of interest for its text-parsing techniques.
As the comments note, it's generally better to make an external program emit structured text, such as JSON, because parsing for-display formatted text is inherently brittle.
According to the kubectl
docs, you can use -o json
to achieve that (as Mathias has also noted).
If the data is simple enough so that plain-text parsing is still an option, you can try the following, which relies on the unary form of the -split
operator to break each line into fields:
# Sample output from kubectl.
# Note: Capturing output from an external programs such as kubectl
# results in an *array of lines*.
# The -split '\r?\n` operation splits the multiline here-string into
# just that.
$kubeCtlOutput = @'
NAME STATUS AGE
dread-gorge Active 28d
dread-lagoon Active 31d
carncier-basin Active 16d
chantague-shallows Active 164d
'@ -split '\r?\n'
# Process the array's lines.
[array] $namesOfInterest =
$kubeCtlOutput |
Select-Object -Skip 1 |
ForEach-Object {
$name, $age = (-split $_)[0, -1]
if ([int] ($age -replace '\D') -gt 30) {
$name
}
}
$namesOfInterest # Print the result.
Output, showing that only the names of the two lines whose AGE
is greater than 30
days were extracted:
dread-lagoon
chantague-shallows
This related question has answers that define generic helper functions that can parse columnar plain-text data into objects.