Powershell заменяет текст один раз в строке - PullRequest
0 голосов
/ 14 декабря 2018

У меня есть сценарий Powershell, который я пытаюсь отработать частично, поэтому в текстовом вводе указывается группа пользователей, в которую они входят.Этот сценарий PS должен заменить группу группами, которые я назначаю им в активном каталоге (я ограничен только изменением групп в активном каталоге).Моя проблема заключается в том, что когда он достигает HR и заменяет его, он затем продолжает работать и заменяет все новое, но все это заменяет HR в CHRL, поэтому мои группы выглядят чокнутыми прямо сейчас.Но я просматриваю это, и это не делает это с каждой строкой.Но для gilchrist это добавит что-то для HR во имя.Могу ли я что-то сделать, чтобы сохранить его для изменения, или мне придется изменить свой персонал в отдел кадров?Спасибо за помощь.

$lookupTable = @{
'Admin' = 'W_CHRL_ADMIN_GS,M_CHRL_ADMIN_UD,M_CHRL_SITE_GS'
'Security' = 'W_CHRL_SECURITY_GS,M_CHRL_SITE_GS'
'HR' = 'M_CHRL_HR_UD,W_CHRL_HR_GS,M_CHRL_SITE_GS'

    $original_file = 'c:\tmp\test.txt'
    $destination_file =  'c:\tmp\test2.txt'

    Get-Content -Path $original_file | ForEach-Object {
        $line = $_

        $lookupTable.GetEnumerator() | ForEach-Object {
            if ($line -match $_.Key)
            {
                $line = $line -replace $_.Key, $_.Value
            }
        }
       $line
    } | Set-Content -Path $destination_file

    Get-Content $destination_file

test.txt:

user,group 
john.smith,Admin 
joanha.smith,HR 
john.gilchrist,security
aaron.r.smith,admin
abby.doe,secuity 
abigail.doe,admin

Ответы [ 2 ]

0 голосов
/ 14 декабря 2018

Почему бы вам не загрузить текстовый файл как CSV-файл , используя Import-CSV, и использовать "," в качестве разделителя?Это позволит вам иметь объект Powershell, с которым вы можете работать.и затем экспортируйте это как текст o CSV.если я использую ваш файл и справочную таблицу, этот код может вам помочь:

$file = Import-Csv -Delimiter "," -Path "c:\ps\test.txt"

$lookupTable = @{
'Admin' = 'W_CHRL_ADMIN_GS,M_CHRL_ADMIN_UD,M_CHRL_SITE_GS'
'Security' = 'W_CHRL_SECURITY_GS,M_CHRL_SITE_GS'
'HR' = 'M_CHRL_HR_UD,W_CHRL_HR_GS,M_CHRL_SITE_GS'}


foreach ($i in $file) {

   #Compare and replace
   ...


}

Export-CSV $file -Delimiter ","

Затем вы можете выполнить итерацию по $file, сравнить и заменить.Вы также можете Export-CSV после того, как закончите.

0 голосов
/ 14 декабря 2018

Ваш ввод выглядит в формате CSV (хотя учтите, что в строках вашего образца есть конечные пробелы, с которыми вам придется иметь дело, если они являются частью ваших фактических данных).

Поэтому используйте Import-Csv и Export-Csv для чтения / перезаписи ваших данных, что позволяет получить более краткое и удобное решение:

Import-Csv test.txt |
  Select-Object user, @{ Name='group'; Expression = { $lookupTable[$_.group] } } |
    Export-Csv -NoTypeInformation -Encoding Utf8 test2.txt
  • Import-Csv считывает файл CSV как коллекцию пользовательских объектов , свойства которых соответствуют значениям столбца CSV;то есть каждый объект имеет свойство .user и .name в вашем случае.

  • $_.group, поэтому надежно сообщает только абстрактное имя группы, которое вы можете напрямую передать вашемупоиск по хеш-таблице;Select-Object используется для передачи исходного значения .user и замены исходного значения .group результатом поиска, используя вычисленное свойство .

  • Export-Csv повторно преобразовывает пользовательские объекты в файл CSV:

    • -NoTypeInformation подавляет (обычно бесполезную) строку информации о типе данных в верхней части выходного файла
    • -Encoding Utf8 было добавлено для предотвращения возможной потери данных, поскольку по умолчанию используется кодировка ASCII.
    • Обратите внимание, что Export-Csv вслепую двойные кавычки все значения полей, нужно им это или нет;Тем не менее, читатели CSV должны быть в состоянии справиться с этим (и Import-Csv, безусловно, делает).

Что касается то, что вы пытались :

Оператор -replace заменяет все вхождения данного регулярного выражения (регулярного выражения) во входных данных.

Ваши регулярные выражения сводятся к поиску (без учета регистра) подстрок , которая объясняет, почему HR соответствует как HR имени группы, так и подстроке hr в имени пользователя gilchrist.

Простой обходной путь - добавить утверждения в регулярное выражение, чтобы подстроки соответствовали толькогде вы хотите их;Например: ,HR$ будет соответствовать только после , в конце строки ($).

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

# Split the row into fields.
$fields = $line -split ','

# Update the group value (last field)
$fields[-1] = $lookupTable[$fields[-1]]

# Rebuild the line
$line = $fields -join ','

Обратите внимание, что вам нужно сделать исключение для строки заголовка (например, проверить, является ли результат поискапусто и воздерживаться от обновления, если это так).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...