考虑以下命令:
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"
]
]
本质上,这类似于将 object
转换为 array
。
如何在 PowerShell 中将命令的结果转换为二维数组?
答案 0 :(得分:2)
要制作与您展示的完全一样的二维数组,您可以这样做。
ls -l | Select-Object -Skip 1 | %{, -split $_ | ConvertTo-Json}
然而,为了让可用的对象具有属性,我喜欢这个秘诀。
$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;DR
switch 语句非常适合读取来自文件、命令输出等的行。我们只抓取那些与正则表达式匹配的行。
正则表达式说明
.+?
表示匹配任意数量的任意字符,但尽可能少。( )
将任何与括号中的模式匹配的内容放入捕获组中。默认情况下将编号为组,如果您愿意,可以为它们命名。\s
匹配单个空格\w{3}
匹配 3 个单词字符:
匹配文字冒号\d{1,}
匹配一位或多位数字$
行尾。 (在此之前的匹配必须在行尾)因此我们捕获 $matches.1
中的前 5 列、$matches.2
中的时间戳以及 $matches.3
中的其余文本(应该是文件/文件夹名称)>
从那里我们通过将拆分放在首位来拆分 $matches.1
。通常,当您拆分并向下发送管道时,它一次一个。
-split "a b c" | %{"$_"}
通过在前面添加逗号将其转换为数组并按原样发送到管道中。
, -split "a b c" | %{"$_"}
然后我们只需将每个值放在正确的位置。也可以转成 JSON 对象。
答案 1 :(得分:1)
有了这个,您可以将 ls -l
的结果转换为 PS 对象,然后可以通过管道将其传输到 ConvertTo-Json
,以防您需要 Json 作为结果。现在我不太擅长正则表达式,这个例子只有在文件/文件夹没有空格时才有效。如果有人可以帮助使用正确的正则表达式来拆分它,那就太好了:
$lsObject=ls -l|select -skip 1|%{
$tmp=$_ -split '\s{1,}'
[PSCustomObject]@{
Permission = $tmp[0]
Links = $tmp[1]
Owner = $tmp[2]
Group = $tmp[3]
Size = $tmp[4]
LastModified = '{0} {1} {2}' -f $tmp[5],$tmp[6],$tmp[7]
FileName = $tmp[8]
}
}