PowerShell将字符串分割为二维数组

3

TL:DR

我想使用PowerShell将一个文本字符串首先按换行符(\n)拆分,将其存储到数组中,然后将这些数组条目用逗号拆分成二维数组。 我无法访问(或可能创建)第二维中的任何信息。

INFO:

我有以下字符串(存储为$services):

SUPER-PC,Microsoft Office ClickToRun Service,ClickToRunSvc,C:\Program Files\Microsoft Office 15\ClientX64\OfficeClickToRun.exe /service,Auto
SUPER-PC,Adobe Acrobat Update Service,AdobeARMservice,C:\Program Files (x86)\Common Files\Adobe\ARM\1.0\armsvc.exe,Auto

期望结果:

我想要对字符串进行两次分割:

  1. 按照换行符(第一维)进行分割
  2. 在每一行内按逗号(第二维)进行分割

我希望最终的结果是一个可以引用的二维数组。(例如:$services [0] [0]等)

使用的命令:

为了实现换行符的分割,我使用了以下命令:

$services= $services -split "\n"

为了访问新数组结构中的分割字符串,我可以执行以下操作:
$services[0]

PowerShell仅显示$services的第一行。

接下来我使用:

$services[0] = $services[0] -split ','

问题:

当我尝试使用$services[0][0]访问第一个数组的第二维时,它显示了字符数组的第一个字符(“SUPER-PC”是字符串的开始),而不是我想要创建的二维数组。

我做错了什么?

4个回答

6

-split 返回一个 string[] 类型的对象,这意味着你不能将除字符串以外的任何类型赋值给单个项目而不改变整个数组的类型。

当解析器看到你尝试将新数组分配给现有的 $services 字符串数组中的一个项目时,它会自动将新数组转换为一个由 $OFS 连接的字符串。由于 $OFS 默认为空格,因此你实际上将这个字符串转换成了:

SUPER-PC,Microsoft Office ClickToRun Service,ClickToRunSvc,C:\Program Files\Microsoft Office 15\ClientX64\OfficeClickToRun.exe /service,Auto

将其转换为字符串:
SUPER-PC Microsoft Office ClickToRun Service ClickToRunSvc C:\Program Files\Microsoft Office 15\ClientX64\OfficeClickToRun.exe /service Auto

相反,创建一个全新的数组来保存结果数组:
$Services = @'
SUPER-PC,Microsoft Office ClickToRun Service,ClickToRunSvc,C:\Program Files\Microsoft Office 15\ClientX64\OfficeClickToRun.exe /service,Auto
SUPER-PC,Adobe Acrobat Update Service,AdobeARMservice,C:\Program Files (x86)\Common Files\Adobe\ARM\1.0\armsvc.exe,Auto
'@

# I prefer a more OS-agnostic newline pattern
$Services = $Services -split "`r?`n"

# Create a new array, defaults to Object[], so can contain arrays as well
$MultiDimensionalServices = @()

# Iterate over each string in $Services
foreach($ServiceString in $Services){
    # use the unary array operator (,) to avoid flattening the array
    $MultiDimensionalServices += ,@($ServiceString -split ',')
}

我会试一试!谢谢! - Shrout1

4

好的,我很不想自己回答,但这比我想象的要简单得多...其他两个答案都是正确的,而Mathias指出了一个明显的疏忽。

$string = $string -split "," 不等于 $string = $string.split(",") 如Mathias所说:

-split 返回一个类型为 string[] 的对象,这意味着你不能将除字符串以外的任何东西分配给单个项目,否则会改变整个数组的类型。

所以我最终使用了:

$services= $services.split("`r`n")

然后

$services[0]= $services[0].split(",")

然后我就能够成功地使用 services[0][0] 访问多维数组的第二个维度了。

此外,Bacon Bit的答案很可能比我的答案更好;我的答案只是以最简单的方式回答了我的问题。


4

你不这样做的原因是什么:

$ConvertedServices = $Services | ConvertFrom-Csv -Header 'ComputerName','ServiceDescription','ServiceName','CommandLine','StartUp'

然后:

$ConvertedServices[0].ComputerName

在PowerShell中,多维数组确实可用,但是它们使用起来有点棘手,尤其是对于字符串而言,因为字符串经常被视为字符数组,就像你在这里遇到的问题一样。

不知道这个!我在PowerShell方面还是个新手 :) 我正在消化你的回答 - 谢谢! - Shrout1
好的 - 当我运行转换时,我只得到两个实例的"超级电脑"在两行上... 头部需要已经存在于数据中吗?也就是说,我是否需要有一行标题,或者那些值是在-Header中定义的? - Shrout1
抱歉,那是我的错。-Header 是一个字符串数组,而不是逗号分隔的字符串。我已经更新了它。ConvertFrom-Csv 假设第一行是标题行。-Header 参数用于为没有标题行的数据定义一个标题行。 - Bacon Bits
我不得不说,这对于CSV数据非常有效;感谢您提供答案并进行修订 :) - Shrout1
是的,在PowerShell中有几个工具可以很方便地处理CSV文件。ConvertFrom-CsvConvertTo-CsvImport-CsvExport-Csv。使用这些工具可以轻松处理数据文件。 - Bacon Bits

2

试试这个

$Services=("SUPER-PC,Microsoft Office ClickToRun Service,ClickToRunSvc,C:\Program Files\Microsoft Office 15\ClientX64\OfficeClickToRun.exe /service,Auto",
"SUPER-PC,Adobe Acrobat Update Service,AdobeARMservice,C:\Program Files (x86)\Common Files\Adobe\ARM\1.0\armsvc.exe,Auto")

$ConvertedServices = $Services | ConvertFrom-String -Delimiter "," -PropertyNames 'ComputerName','ServiceDescription','ServiceName','CommandLine','StartUp'
$ConvertedServices[0].ComputerName

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接