PowerShell解析这些字符串的最佳方法是什么?

时间:2016-11-21 13:26:14

标签: powershell csv parsing

我将两个字符串传递到我的脚本中:

"Project1,Project2,Project3,Project4"
"web,batch,web,components"

字符串来自DevOps工具链中的工具,我无法控制输入格式。字符串1可以是任意数量的项目。字符串2将与"类型"相同数量的条目。字符串1中的项目。

我需要为第二个字符串中的每个不同类型发出一个字符串,其中包含第一个字符串中的项目:

"Project1,Project3"
"Project2"
"Project4"

我知道我可以用一堆嵌套的foreach循环来做到这一点。有没有办法用哈希表和/或数组做到这一点?

3 个答案:

答案 0 :(得分:6)

您可以使用-split运算符将原始输入字符串转换为数组:

$ProjectNames = "Project1,Project2,Project3,Project4" -split ','
$ProjectTypes = "web,batch,web,components" -split ','

然后创建一个空哈希表以包含类型到项目名称的映射

$ProjectsByType = @{}

最后迭代两个数组,按类型对项目名称进行分组:

for($i = 0; $i -lt $ProjectNames.Count; $i++){
    if(-not $ProjectsByType.ContainsKey($ProjectTypes[$i])){
        # Create key and entry as array if it doesn't already exist
        $ProjectsByType[$ProjectTypes[$i]] = @()
    }
    # Add the project to the appropriate project type key
    $ProjectsByType[$ProjectTypes[$i]] += $ProjectNames[$i]
}

现在,您可以按项目类型生成所需的字符串:

$ProjectsByType.Keys |ForEach-Object {
    $ProjectsByType[$_] -join ','
}

您还可以从两个阵列创建对象,并使用Group-Object对它们进行分组:

$Projects = for($i = 0; $i -lt $ProjectNames.Count; $i++){
    New-Object psobject -Property @{
        Name = $ProjectNames[$i]
        Type = $ProjectTypes[$i]
    }
}

$Projects |Group-Object -Property Type

如果您想进一步处理项目,如果您只需要第一种方法更容易的字符串

,那就更有意思了

答案 1 :(得分:5)

没有一种优雅的方法可以将两个数组与内置方法相结合。有点令人费解的方式如下:

$projects = $projectString -split ','
$types = $typeString -split ','
0..($projects.Count) | group { $types[$_] } | % { $projects[$_.Group] -join ',' }

然而,这首先在数组中生成索引以便稍后对它们进行分组和格式化,这本质上有点不确定(并且不是很容易理解)。我倾向于预处理数据以实际反映我正在操作的内容:

$projects = $projectString -split ','
$types = $typeString -split ','
$projectsWithType = 0..($projects.Count) | % {
  [pscustomobject]@{
    Project = $projects[$_]
    Type = $types[$_]
  }
}
$projectsWithType | group Type | % { $_.Group -join ',' }

这使得实际数据修改任务更加清晰。

答案 2 :(得分:0)

在第一个列表中只有一个搜索

$projects = "Project1,Project2,Project3,Project4" -split ','
$types = "web,batch,web,components" -split ','

$linenumber = 0

$projects |%{New-Object psObject -Property @{Project=$_;TypeProject= $types[$linenumber]};$linenumber++} |
group TypeProject |
select Name, @{N="Projects";E={$_.Group.Project -join ","}}