Как построить хеш-таблицу из файла с помощью powershell? - PullRequest
1 голос
/ 06 января 2012

У меня есть файл, в котором хранятся компоненты Baseline и имена компонентов, как показано ниже

(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

Затем я попытался создать хеш-таблицу, но первая команда не удалась, и я не знаю, как создать хеш-таблицу из записей файла. Может кто-нибудь помочь мне, пожалуйста?

Ответы [ 3 ]

2 голосов
/ 06 января 2012

Попробуйте:

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

Или

Get-Content $BaselineFile | Foreach-Object { 

    $value = ($_ -replace '@\\My_PVOB|\(|\)').split()

    @{
        key=$value[0]
        value=$value[1] 
    }
}

ОБНОВЛЕНИЕ: Создайте одну хеш-таблицу, ключ хеша сделан из первого совпадения, а его значение равно второму совпадению:

$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
2 голосов
/ 10 января 2012

На момент написания статьи есть два ответа (один от Шэй Леви и один от Джона З), которые оба близки, но ни один не совсем прав - несмотря на то, что ответ Шей уже был принят (!).И вот почему:

Проблемы с кодом Шея

Ответ Шей слишком буквальный, основанный на неточно сформулированном требовании, определяющем создание «хэш-таблицы, которая может иметь записи типа«это:

@(Key=Mailcomp,Value=BL_2.1.0.9.5179)
@(Key=OfficeComp, Value=BL_2.1.0.17.6972)

Но если кто-то собирается использовать синтаксис PowerShell, это указано неверно.В действительности требование должно выглядеть следующим образом:

@{Mailcomp=BL_2.1.0.9.5179}
@{OfficeComp=BL_2.1.0.17.6972}

То есть в первой строке указывается хеш ключ из Mailcomp и хеш значение BL_2.1.0.9.5179.Эта модифицированная версия кода Шэя обеспечивает именно то, что:

$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"] для получения их соответствующих значений.

Вторая проблема с кодом Шэя заключается в самом создании хеш-записи (@{ key=$matches[1]; value=$matches[2] }).Этот оператор создает отдельную «мини» хеш-таблицу для каждой итерации (т.е. для каждой строки ввода).Только кажется , чтобы произвести разумный вывод из-за объединения неявного Write-Output в его коде.Чтобы доказать это - и сравнить яблоки с яблоками - возьмите мой код выше и замените условное выражение на этот эквивалент кода Шея:

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

Вы обнаружите, что $hash["Mailcomp"] делает не вернуть ожидаемое BL_2.1.0.9.5179.

Проблемы с кодом Джона

Мне нравится ответ Джона З;Я действительно так делаю.В самом деле.Но это напоминает мне о великой старой шутке с изюминкой Предположим, у нас есть консервный нож ... Это очень хорошее решение тогда и только тогда, когда ввод поддается простому разделителю.Дело не в этом - для массажа требуется регулярное выражение (или другой механизм).Справедливости ради, Джон отмечает, что явно заявляя, что он предполагает некоторую предварительную обработку.`Нуфф сказал.

2 голосов
/ 06 января 2012

Предполагая, что ваш $ 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...