Regex 如何使用powershell从文件构造哈希表?

Regex 如何使用powershell从文件构造哈希表?,regex,powershell,powershell-2.0,Regex,Powershell,Powershell 2.0,我有一个文件,其中组件基线和组件名称存储如下 (Mailcomp@\My_PVOB) BL_2.1.0.9.5179@\My_PVOB (OfficeComp@\My_PVOB) BL_2.1.0.17.6972@\MY_PVOB 实际上,我需要构造一个哈希表,它可能有如下条目 @(Key=Mailcomp,Value=BL_2.1.0.9.5179) @(Key=OfficeComp, Value=BL_2.1.0.17.6972) 我试着替换如下内容 (Get-Content $Base

我有一个文件,其中组件基线和组件名称存储如下

(Mailcomp@\My_PVOB) BL_2.1.0.9.5179@\My_PVOB
(OfficeComp@\My_PVOB) BL_2.1.0.17.6972@\MY_PVOB
实际上,我需要构造一个哈希表,它可能有如下条目

@(Key=Mailcomp,Value=BL_2.1.0.9.5179)
@(Key=OfficeComp, Value=BL_2.1.0.17.6972)
我试着替换如下内容

(Get-Content $BaselineFile) | foreach{ $_ -replace "@\My_PVOB[?]",''} | Out-File  $BaselineFile

然后我尝试创建哈希表,但是第一个命令本身失败了,我不知道如何从文件条目创建哈希表。有人能帮我吗?

假设您的$baselinefile在预处理后是这样的:

Mailcomp BL_2.1.0.9.5179
OfficeComp BL_2.1.0.17.6972
这应该起作用:

$hash = @{}
Import-Csv $BaseLineFile -header "first", "second" -delimiter " " | ForEach-Object { $hash[$_.first] = $_.second}
$hash

假设$baselinefile在预处理后如下所示:

Mailcomp BL_2.1.0.9.5179
OfficeComp BL_2.1.0.17.6972
这应该起作用:

$hash = @{}
Import-Csv $BaseLineFile -header "first", "second" -delimiter " " | ForEach-Object { $hash[$_.first] = $_.second}
$hash
尝试一下:

Get-Content $BaselineFile | Foreach-Object { 
    if($_ -match '^\(([^@]+).+\)\s([^@]+)')
    {
        @{
            key=$matches[1]
            value=$matches[2]   
        }
    }
}

Name    Value
----    -----
value   BL_2.1.0.9.5179
key     Mailcomp
value   BL_2.1.0.17.6972
key     OfficeComp

更新:创建一个哈希表,哈希键由第一个匹配项组成,其值为第二个匹配项:

$ht = @{}

Get-Content $BaselineFile | Foreach-Object {     

    if($_ -match '^\(([^@]+).+\)\s([^@]+)')
    {        
            $ht[$matches[1]] = $matches[2]     
    }    
}

$ht

Name       Value           
----       -----           
Mailcomp   BL_2.1.0.9.5179 
OfficeComp BL_2.1.0.17.6972
尝试一下:

Get-Content $BaselineFile | Foreach-Object { 
    if($_ -match '^\(([^@]+).+\)\s([^@]+)')
    {
        @{
            key=$matches[1]
            value=$matches[2]   
        }
    }
}

Name    Value
----    -----
value   BL_2.1.0.9.5179
key     Mailcomp
value   BL_2.1.0.17.6972
key     OfficeComp

更新:创建一个哈希表,哈希键由第一个匹配项组成,其值为第二个匹配项:

$ht = @{}

Get-Content $BaselineFile | Foreach-Object {     

    if($_ -match '^\(([^@]+).+\)\s([^@]+)')
    {        
            $ht[$matches[1]] = $matches[2]     
    }    
}

$ht

Name       Value           
----       -----           
Mailcomp   BL_2.1.0.9.5179 
OfficeComp BL_2.1.0.17.6972

在撰写本文时,有两个答案(一个来自Shay Levy,一个来自jon Z)都很接近,但都不完全正确——尽管Shay的答案已经被接受(!)。原因如下:

关于Shay代码的问题

Shay的答案过于直白,基于一个不准确的要求,该要求指定创建一个“哈希表,该哈希表可能包含以下条目”:

但如果要使用PowerShell语法,则说明不正确。实际要求应如下所示:

@(Key=Mailcomp,Value=BL_2.1.0.9.5179)
@(Key=OfficeComp, Value=BL_2.1.0.17.6972)
@{Mailcomp=BL_2.1.0.9.5179}
@{OfficeComp=BL_2.1.0.17.6972}
也就是说,第一行指定了
Mailcomp
的hash键和
BL_2.1.0.9.5179
的hash值。Shay代码的这个修改版本正好提供了:

$hash = @{}
Get-Content $BaselineFile | 
Foreach-Object {
    if ($_ -match '^\(([^@]+).+\)\s([^@]+)')
    {
        $hash[$matches[1]]=$matches[2]
    }
}
以下是输出:

Name       Value
----       -----
Mailcomp   BL_2.1.0.9.5179
OfficeComp BL_2.1.0.17.6972
这更容易使用,因为我现在可以访问
$hash[“Mailcomp”]
$hash[“OfficeComp”]
来检索它们各自的值

Shay代码的第二个问题是散列项创建本身(
@{key=$matches[1];value=$matches[2]}
)。该语句为每个迭代(即输入的每一行)创建一个单独的“迷你”哈希表。它似乎只产生合理的输出,因为在他的代码中合并了隐式写输出。为了证明这一点——并将苹果与苹果进行比较——以我上面的代码为例,将条件替换为与Shay的代码等效的代码:

    if ($_ -match '^\(([^@]+).+\)\s([^@]+)')
    {
        @{ $matches[1]=$matches[2] }
    }
您会发现,
$hash[“Mailcomp”]
不会返回预期的
BL_2.1.0.9.5179

Jon代码的问题


我喜欢乔恩的回答;我真的喜欢。真正地但它让我想起了一个伟大的老笑话,其中有一条妙语:当且仅当输入服从一个简单的定界符时,这是一个非常好的解决方案。这里的情况并非如此——需要正则表达式(或其他机制)来处理输入。公平地说,Jon明确指出,他正在进行一些预处理`努夫说。

在撰写本文时,有两个答案(一个来自Shay Levy,一个来自jon Z)都很接近,但都不完全正确——尽管Shay的答案已经被接受(!)。原因如下:

关于Shay代码的问题

Shay的答案过于直白,基于一个不准确的要求,该要求指定创建一个“哈希表,该哈希表可能包含以下条目”:

但如果要使用PowerShell语法,则说明不正确。实际要求应如下所示:

@(Key=Mailcomp,Value=BL_2.1.0.9.5179)
@(Key=OfficeComp, Value=BL_2.1.0.17.6972)
@{Mailcomp=BL_2.1.0.9.5179}
@{OfficeComp=BL_2.1.0.17.6972}
也就是说,第一行指定了
Mailcomp
的hash键和
BL_2.1.0.9.5179
的hash值。Shay代码的这个修改版本正好提供了:

$hash = @{}
Get-Content $BaselineFile | 
Foreach-Object {
    if ($_ -match '^\(([^@]+).+\)\s([^@]+)')
    {
        $hash[$matches[1]]=$matches[2]
    }
}
以下是输出:

Name       Value
----       -----
Mailcomp   BL_2.1.0.9.5179
OfficeComp BL_2.1.0.17.6972
这更容易使用,因为我现在可以访问
$hash[“Mailcomp”]
$hash[“OfficeComp”]
来检索它们各自的值

Shay代码的第二个问题是散列项创建本身(
@{key=$matches[1];value=$matches[2]}
)。该语句为每个迭代(即输入的每一行)创建一个单独的“迷你”哈希表。它似乎只产生合理的输出,因为在他的代码中合并了隐式写输出。为了证明这一点——并将苹果与苹果进行比较——以我上面的代码为例,将条件替换为与Shay的代码等效的代码:

    if ($_ -match '^\(([^@]+).+\)\s([^@]+)')
    {
        @{ $matches[1]=$matches[2] }
    }
您会发现,
$hash[“Mailcomp”]
不会返回预期的
BL_2.1.0.9.5179

Jon代码的问题


我喜欢乔恩的回答;我真的喜欢。真正地但它让我想起了一个伟大的老笑话,其中有一条妙语:当且仅当输入服从一个简单的定界符时,这是一个非常好的解决方案。这里的情况并非如此——需要正则表达式(或其他机制)来处理输入。公平地说,Jon明确指出,他正在进行一些预处理`努夫说。

利维的简单易懂的答案同样令人震惊。它可以工作,伙计,也可以理解这是未命名的散列。如何将其存储在命名哈希中?因此,我可以处理散列中的每个值并再执行一次操作。您可以将结果分配给一个变量,并使用其集合索引处理每个值。比如:$h=gc。。。然后是$h[0]。正如“msorens”所提到的,关键etcBuddy,您的代码有问题吗?我使用了你的代码中的替换方法,以及我从JonZ那里使用的其他东西,我不确定这个理论。Gain Levy的易懂答案令人震惊。它可以工作,伙计,也可以理解这是未命名的散列。如何将其存储在命名哈希中?因此,我可以处理散列中的每个值并再执行一次操作。您可以将结果分配给一个变量,并使用其集合索引处理每个值。比如:$h=gc。。。然后是$h[0]。正如“msorens”所提到的,关键etcBuddy,您的代码有问题吗?我已经从你的代码中使用了replace方法,我从JonZ中使用了其余的东西,对此我不确定