首页 > 解决方案 > 如何将命令的结果转换为 PowerShell 中的二维数组?

问题描述

已知

考虑以下命令:

ls -l

-rwx------  123 ladiesman217  root    549 Apr 01 01:01 one.txt
-rwx------  123 ladiesman217  root    549 Apr 01 02:02 two.txt
-rwx------  123 ladiesman217  root    549 Apr 01 03:03 three.txt

当通过管道传输到 时ConvertTo-Json,它会创建一个数组,如下所示:

ls -l | ConvertTo-Json

[
  "-rwx------  123 ladiesman217  root    549 Apr 01 01:01 one.txt",
  "-rwx------  123 ladiesman217  root    549 Apr 01 02:02 two.txt",
  "-rwx------  123 ladiesman217  root    549 Apr 01 03:03 three.txt"
]

客观的

有没有一种快速的方法可以将其变成二维数组,例如:

[
  [
    "-rwx------",
    "123",
    "ladiesman217",
    "root",
    "549",
    "Apr",
    "01",
    "01:01",
    "one.txt"
  ],
  [
    "-rwx------",
    "123",
    "ladiesman217",
    "root",
    "549",
    "Apr",
    "01",
    "02:02",
    "two.txt"
  ],
  [
    "-rwx------",
    "123",
    "ladiesman217",
    "root",
    "549",
    "Apr",
    "01",
    "03:03",
    "three.txt"
  ]
]

从本质上讲,这就像将 anobject转换为array.

如何将命令的结果转换为 PowerShell 中的二维数组?

标签: jsonpowershell

解决方案


要制作与您展示的完全相同的二维数组,您可以执行此操作。

   ls -l | Select-Object -Skip 1 | %{, -split $_ | ConvertTo-Json}

在此处输入图像描述


然而,为了制作具有属性的可用对象,我喜欢这个食谱。

  • 切换语句
  • 足够的正则表达式
  • 一小撮字符串操作
  • 一元运算符
  • PSCustomObject
    $output = switch -Regex (ls -l){
        '(.+?)\s(\w{3}\s.+?:\d{1,})\s(.+?)$' {
            , -split $matches.1 | Foreach-Object {
                [PSCustomObject]@{
                    Permission = $_[0]
                    Links      = $_[1]
                    Owner      = $_[2]
                    Group      = $_[3]
                    Size       = $_[4]
                    Modified   = $matches.2
                    FileName   = $matches.3
                }
            }
        }
    }

    $output | Format-Table

输出 在此处输入图像描述

TL;博士

switch 语句非常适合读取来自文件、命令输出等的行。我们只抓取那些与正则表达式模式匹配的行。

正则表达式解释

  • .+?表示匹配任意数量的任意字符,但尽可能少。
  • ( )将与括号中的模式匹配的任何内容放在捕获组中。默认情况下,将编号组,如果您愿意,可以命名它们。
  • \s匹配一个空格
  • \w{3}匹配 3 个单词字符
  • :匹配文字冒号
  • \d{1,}匹配一个或多个数字
  • $行尾。(在此之前的匹配必须在行尾)

因此,我们捕获 中的前 5 列$matches.1、中的时间戳$matches.2和中的其余文本(应该是文件/文件夹名称)$matches.3

从那里我们$matches.1通过将拆分放在第一位来拆分空间。通常,当您拆分并向下发送管道时,它将一次一个。

-split "a b c" | %{"$_"}

在此处输入图像描述

通过将逗号添加到前面,将其转换为数组并按原样发送到管道中。

, -split "a b c" | %{"$_"}

在此处输入图像描述

然后我们只需将每个值放在正确的位置。你也可以变成一个 JSON 对象。

在此处输入图像描述


推荐阅读