Powershell 如何组合字符串输入并动态生成数组?

Powershell 如何组合字符串输入并动态生成数组?,powershell,Powershell,假设我像这样在命令行上传递输入 param([string]$roles,[string]$members) 我希望这方面的阵列是: PS> role1,role2,role3,role4 member1,member2,,,,member3,,member4 我知道如何将字符串转换为数组: $array = @( @('role1', 'member1,member2'), @('role2', ''), @('role3', 'member3'),

假设我像这样在命令行上传递输入

param([string]$roles,[string]$members)
我希望这方面的阵列是:

PS> role1,role2,role3,role4 member1,member2,,,,member3,,member4
我知道如何将字符串转换为数组:

$array = @(
    @('role1', 'member1,member2'),
    @('role2', ''),
    @('role3', 'member3'),
    @('role4', 'member4')
)
现在,我如何将$roles与$members组合起来,以便每个角色都与成员关联?如何动态生成数组

伪代码:

注意:我将成员拆分为每个双逗号的索引,因为在命令行上显然不接受分号,因为分号会打断命令行,所以我必须使用双逗号作为分隔符


注2:请注意4个逗号:,,,这表示role2没有要添加的成员,因此本质上这意味着这4个逗号之间没有该索引/项目role2的成员输入,即,空,,

如果您确实想使用此参数格式,可以按如下方式创建所需的输出数组:

$array = @()

($roles+$members) | %{
    $role = $_.roles
    if ($_.members) {
        $_.members -split ',,' | ForEach-Object { $array += $role $_ }
    } else {
        $array += $role 
    }
}
请注意,如果您从PowerShell传递参数,则需要引用它们,否则PowerShell会将它们解析为数组

引用你可以自由使用;例如,代替、、来分隔成员组

表示参数数据以便以后处理的更好方法是创建自定义对象数组,而不是嵌套数组:

$roles = 'role1,role2,role3,role4' -split ','
$members = 'member1,member2,,,,member3,,member4' -split ',,'

$i = 0
$array = @(foreach ($role in $roles) {
  , ($role, $members[$i++])
})
$array中的每个对象现在都有一个.Role和一个.Members属性,后者将单个成员作为字符串数组包含

或者,您也可以从输入中创建一个[n有序]哈希表,由角色名称键入,但这仅在您需要按名称访问角色或要排除已指定的重复角色时才有必要

下面是一种更容易理解的替代参数格式:

$roles = 'role1,role2,role3,role4' -split ','
$members = 'member1,member2,,,,member3,,member4' -split ',,'

$i = 0
$array = @(foreach ($role in $roles) {
   [pscustomobject] @{
     Role = $role
     Members = $members[$i++] -split ','
   }
})

如果您确实希望使用此参数格式,可以按如下方式创建所需的输出数组:

$array = @()

($roles+$members) | %{
    $role = $_.roles
    if ($_.members) {
        $_.members -split ',,' | ForEach-Object { $array += $role $_ }
    } else {
        $array += $role 
    }
}
请注意,如果您从PowerShell传递参数,则需要引用它们,否则PowerShell会将它们解析为数组

引用你可以自由使用;例如,代替、、来分隔成员组

表示参数数据以便以后处理的更好方法是创建自定义对象数组,而不是嵌套数组:

$roles = 'role1,role2,role3,role4' -split ','
$members = 'member1,member2,,,,member3,,member4' -split ',,'

$i = 0
$array = @(foreach ($role in $roles) {
  , ($role, $members[$i++])
})
$array中的每个对象现在都有一个.Role和一个.Members属性,后者将单个成员作为字符串数组包含

或者,您也可以从输入中创建一个[n有序]哈希表,由角色名称键入,但这仅在您需要按名称访问角色或要排除已指定的重复角色时才有必要

下面是一种更容易理解的替代参数格式:

$roles = 'role1,role2,role3,role4' -split ','
$members = 'member1,member2,,,,member3,,member4' -split ',,'

$i = 0
$array = @(foreach ($role in $roles) {
   [pscustomobject] @{
     Role = $role
     Members = $members[$i++] -split ','
   }
})

您的参数格式非常奇怪,但有一种方法:

$rolesAndMembers = 'role1 = member1,member2 ; role2= ; role3=member3 ; role4=member4'

$array = @(foreach ($roleAndMembers in ($rolesAndMembers -replace ' ' -split ';')) {
  $role, $members = $roleAndMembers -split '='
  [pscustomobject] @{
    Role = $role
    Members = $members -split ','
  }
})

我建议重新设计脚本以使用标准的PowerShell参数。我认为,工程工作是值得的。

您的参数格式非常奇怪,但有一种方法:

$rolesAndMembers = 'role1 = member1,member2 ; role2= ; role3=member3 ; role4=member4'

$array = @(foreach ($roleAndMembers in ($rolesAndMembers -replace ' ' -split ';')) {
  $role, $members = $roleAndMembers -split '='
  [pscustomobject] @{
    Role = $role
    Members = $members -split ','
  }
})

我建议重新设计脚本以使用标准的PowerShell参数,我认为这是值得的。我强烈建议使用哈希表/字典来传递这些角色映射:

$roles = 'role1,role2,role3,role4' -split ','
$members = 'member1,member2,,,,member3,,member4' -split ',,'

$result = @()
for ( $i = 0; $i -lt $roles.Count; $i++ ) {
  $result += ,@($roles[$i],$members[$i])
}
可以从当前输入字符串中使用其中一个构造输入参数:

param(
    [System.Collections.IDictionary]$RoleMembers
)

# now we can access each mapping by role name:
$RoleMembers['role1'] # member1, member2

# or iterate over them like an array:
foreach($role in $RoleMembers.Keys){
    $RoleMembers[$role]
}

我强烈建议使用哈希表/字典来传递这些角色映射:

$roles = 'role1,role2,role3,role4' -split ','
$members = 'member1,member2,,,,member3,,member4' -split ',,'

$result = @()
for ( $i = 0; $i -lt $roles.Count; $i++ ) {
  $result += ,@($roles[$i],$members[$i])
}
可以从当前输入字符串中使用其中一个构造输入参数:

param(
    [System.Collections.IDictionary]$RoleMembers
)

# now we can access each mapping by role name:
$RoleMembers['role1'] # member1, member2

# or iterate over them like an array:
foreach($role in $RoleMembers.Keys){
    $RoleMembers[$role]
}

嵌入a字符串分号将起作用。只有不在字符串中的才被视为命令分隔符。//你为什么不使用-RoleMember'Role\u a;人员1、人员2、角色B;人员2’,“角色4”;人物1,人物5’?@Lee_Dailey TBH,剧本太复杂了,无法更改。我不知道如何解析这样的输入。我可以根据您的建议创建一个名为$RoleMember的通用变量,但为了尽量减少脚本所需的更改量,我需要将$CUBE_角色和$CUBE_成员变量分别设置为解析的$RoleMember组合输入,如果这不需要对现有脚本进行太多更改,我不介意。我建议使用哈希表,而不是包含两个成员的数组。@Cataster-如果您的脚本如此复杂。。。然后,您可能需要在内部将其分解为多个函数,以处理每个函数中强烈建议的最小值。用一个函数换一件狭隘的东西。然后重新编写脚本。//如果这是不可行的,那么您需要编写一个预处理器脚本来收集信息,根据需要对其进行格式化,然后将其提交给太大而无法更改的脚本。//但是,任何时候脚本太大而无法更改或太复杂而无法更改。。。你几乎肯定需要重写它。@Cataster-现实生活。。。[grin]////不过,您可以为它编写一个预处理器来处理复杂的输入。嵌入a字符串分号也可以。只有不在字符串中的才被视为命令分隔符。//你为什么不这么做
不要使用-RoleMember'Role\u A;人员1、人员2、角色B;人员2’,“角色4”;人物1,人物5’?@Lee_Dailey TBH,剧本太复杂了,无法更改。我不知道如何解析这样的输入。我可以根据您的建议创建一个名为$RoleMember的通用变量,但为了尽量减少脚本所需的更改量,我需要将$CUBE_角色和$CUBE_成员变量分别设置为解析的$RoleMember组合输入,如果这不需要对现有脚本进行太多更改,我不介意。我建议使用哈希表,而不是包含两个成员的数组。@Cataster-如果您的脚本如此复杂。。。然后,您可能需要在内部将其分解为多个函数,以处理每个函数中强烈建议的最小值。用一个函数换一件狭隘的东西。然后重新编写脚本。//如果这是不可行的,那么您需要编写一个预处理器脚本来收集信息,根据需要对其进行格式化,然后将其提交给太大而无法更改的脚本。//但是,任何时候脚本太大而无法更改或太复杂而无法更改。。。你几乎肯定需要重写它。@Cataster-现实生活。。。[grin]////不过,您可以为它编写一个预处理器来处理复杂的输入。您对$members的定义不准确。OP的真正含义是-拆分“,”。如果他们用过的话会更好;对于分隔符,如下所示:$members='member1,member2;;成员3;成员4'-拆分';'@一开始我以为我想用的是BaconBits;所以我坚持使用双逗号。但是Lee_Dailey解释说,如果我引用它们,我可以使用分号,我对此很满意。因此,即使使用或不使用分号,我在尝试构造解决方案时也会得到错误的输出:role1 member1,member2 role3 role4 role2{member3,member4}@Cataster请注意,哈希表没有保留顺序,请尝试:$roleMembers.GetEnumerator | sort name谢谢,这确实解决了排序问题,但输出仍然不正确。role2正在获取值{member3,member4},role3和role4为空。正确的输出应该是:role1有member1,member2。角色2是空的。role3有member3,role4有member4在本例中,您对$members的定义不准确。OP的真正含义是-拆分“,”。如果他们用过的话会更好;对于分隔符,如下所示:$members='member1,member2;;成员3;成员4'-拆分';'@一开始我以为我想用的是BaconBits;所以我坚持使用双逗号。但是Lee_Dailey解释说,如果我引用它们,我可以使用分号,我对此很满意。因此,即使使用或不使用分号,我在尝试构造解决方案时也会得到错误的输出:role1 member1,member2 role3 role4 role2{member3,member4}@Cataster请注意,哈希表没有保留顺序,请尝试:$roleMembers.GetEnumerator | sort name谢谢,这确实解决了排序问题,但输出仍然不正确。role2正在获取值{member3,member4},role3和role4为空。正确的输出应该是:role1有member1,member2。角色2是空的。在本例中,role3有member3,role4有member4