Home > Net >  Handling Data & Sorting Results in PowerShell
Handling Data & Sorting Results in PowerShell

Time:11-23

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.

  • Related