Powershell заменяет текст один раз в строке

У меня есть сценарий Powershell, часть которого я пытаюсь проработать, поэтому вводимый текст - это список группы пользователей, частью которой они являются. Этот сценарий PS должен заменить группу группами, которые я назначаю им в активном каталоге (я ограничен только изменением групп в активном каталоге). Моя проблема в том, что когда он достигает HR и заменяет его, он затем переходит к продолжению и заменяет все новое, но все это заменяет HR в CHRL, поэтому сейчас мои группы выглядят сумасшедшими. Но я просматриваю это, и он не делает это с каждой строкой. Но для гилкриста это добавит кое-что для HR в название. Могу ли я что-нибудь сделать, чтобы сохранить его для изменения, или мне придется сменить свой HR на 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
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
399
2

Ответы 2

Ваш ввод находится в формате 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 ','

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

Почему бы вам не загрузить текстовый файл как CSV файл, используя Import-CSV и использовать "," в качестве разделителя? Это позволит вам получить объект Powershell, над которым вы можете работать. а затем экспортируйте его как текст в 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 после того, как закончите.

моя ошибка. Я не обратил на это внимания. вы можете удалить опцию -Header.

Hamza 14.12.2018 20:50

Другие вопросы по теме