Сравните два массива, результаты электронной почты в PowerShell

#arrays #powershell #string-comparison

#массивы #powershell #сравнение строк

Вопрос:

Я пытаюсь сравнить два массива: один содержит список имен пользователей (динамический, иногда больше имен пользователей, иногда меньше), а другой содержит список имен файлов (также динамический). Каждое имя файла содержит имя пользователя вместе с другим текстом, например, «Отчет об имени пользователя [дата].xlsx». Цель состоит в том, чтобы сопоставить элементы между массивом A и массивом B.

Массив A — это просто имена пользователей. Вывод массива A, содержащегося в $Username, просто: PersonA PersonB PersonC и т. Д…

Массив B содержит пути к файлам, но я могу сузить его до просто имен файлов, таких как so $arrayB.Имя (полный путь будет $arrayB.Полное имя). Формат именования для массива B — «Отчет об имени пользователя [дата].xlsx».

Вывод массива B, содержащегося в $LatestFiles.Имя (для имени файла): Отчет о персонаже 1-1-21.xlsx Отчет PersonB 1-1-21.xlsx Отчет PersonC 1-1-21.xlsx

После сопоставления последней частью будет, если элемент в массиве A совпадает с элементом в массиве B, присоедините arrayB.Полное имя к соответствующему имени пользователя «@domain.com «.

К сожалению, я даже не могу заставить соответствие работать должным образом.

Я пробовал:

 foreach ($elem in $UserName) { if ($LatestFiles.Name -contains $elem) { "there is a match" } }
 

и

 foreach ($elem in $UserName) {
    if($LatestFiles.Name -contains $elem) {
        "There is a match"
    } else {
        "There is no match"
    }
}
 

и несколько разных вариантов, но я не могу заставить их выводить совпадения. Любая помощь приветствуется.

Комментарии:

1. $LatestFiles |Where Name -eq $elem чтобы получить коррелированные элементы из $LatestFiles

2. Попробовал это вместо того, что у меня есть, но, к сожалению, это не сработало.

3. Извините за отсутствие ясности, вам нужно будет поместить его внутри foreach цикла (поскольку он ссылается $elem )

4. Нет проблем, я предполагал, что так много lol. Если я заменю «$LatestFiles. Name -содержит $elem» в цикле foreach с вашим предложением, он ничего не выводит. Аналогично, если я заменю весь «оператор if» вашим предложением, вывод также будет пустым. Если информация о массивах недостаточно ясна, я могу добавить больше информации. Еще раз спасибо.

5. Просто перечитайте сообщение, вы захотите ... |Where Name -like "${elem}*" , чтобы оно проверяло, начинается ли имя файла со значения $elem

Ответ №1:

Краткий ответ на вопрос, почему вы не можете получить совпадения: -Contains предназначен для сопоставления значения с коллекцией, а не с String . Вам было бы лучше использовать -Like для вашего оператора сравнения. Или, по крайней мере, вы можете попытаться увидеть, находится ли имя файла, а не просто часть имени, содержащая пользователя, в коллекции имен пользователей.

Похоже, вы не просто сравниваете массивы, а более сложный вопрос о том, что вы делаете с двумя совпадающими элементами.

 $LatestFiles |
    ForEach-Object {
        # first, let's take the formatted file name and make it more usable
        $fileName = $_.BaseName -split ' ' # BaseName over Name so that it strips the extension
        Write-Output @{
            User = $fileName[0]
            Date = $fileName[2]
            File = $_
        }
    } -PipelineVariable FileData |
    # next, only accept valid users
    Where-Object User -In $UserName |
    # note that we don't need the value from $UserName because we already have it in $FileData.User (what we matched)
    ForEach-Object {
        # finally do your thing with it.
        $userWithDomain = "$($FileData.User)@domain.com"
        Write-Output $userWithDomain # or whatever you want
    }
 

Комментарии:

1. Спасибо. Это многому меня научило, в том числе переменной -PipelineVariable, которая чрезвычайно полезна для этого.