在 PowerShell 中处理数据和排序结果

Handling Data & Sorting Results in PowerShell

我在处理从 PowerShell 查询返回的数据时遇到问题。

我的目标是获取所有超过 30 天 (>30d) 的 NAME。

之后,我想将这些结果的名称加载到一个数组中。

我查询返回的数据如下:

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

运行 'Select-Object' 或 'Sort-Object' 过滤输出不起作用。

$output | Select-Object -Property NAME
$output | Sort-Object NAME

更新:

  • 对于将输入转换为 CSV 格式并使用 ConvertFrom-Csv, see 进行解析的高级解决方案。

  • 以下解决方案的文本解析技术可能会引起您的兴趣。


如评论所述,通常最好让外部程序发出 结构化 文本,例如 JSON,因为解析用于显示的格式化文本本质上是脆弱的.
根据 kubectl docs,您可以使用 -o json 来实现(正如 Mathias 也指出的那样)。

如果数据足够简单,纯文本解析仍然是一个选项,您可以尝试以下方法,它依赖于 -split operator 的一元形式将每一行分成字段:

# 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.

输出,显示仅提取了AGE大于30天的两行的名称:

dread-lagoon
chantague-shallows

的答案定义了 可以将柱状纯文本数据解析为对象的通用辅助函数

如果$output是一个单多行字符串,你可以这样做:

$result = ($output -split '\r?\n' -replace '\s+', ',' | ConvertFrom-Csv | Where-Object {[int]($_.Age -replace '\D') -gt 30}).NAME

获取数组中的名称 $result

如果$output已经是一个字符串数组,执行:

$result = ($output -replace '\s+', ',' | ConvertFrom-Csv | Where-Object {[int]($_.Age -replace '\D') -gt 30}).NAME