Справка Powershell: как я могу удалить дубликаты (используя несколько столбцов одновременно, а не последовательно)?

#powershell #csv #duplicates

#powershell #csv-файл #дубликаты

Вопрос:

Я попробовал несколько разных вариантов, основанных на некоторых других статьях stack overflow, но я поделюсь примером того, что у меня есть, и образцом выходных данных, а затем некоторым скомпонованным кодом, надеясь на какое-то направление от сообщества:

C:Scriptscontacts.csv:

 id,first_name,last_name,email
1,john,smith,jsmith@notreal.com
1,jane,smith,jsmith@notreal.com
2,jane,smith,jsmith@notreal.com
2,john,smith,jsmith@notreal.com
3,sam,jones,sjones@notreal.com
3,sandy,jones,sandy@notreal.com
 

Необходимо превратить это в файл, в котором столбец «email» уникален для столбца «id». Другими словами, могут быть повторяющиеся адреса, но только при наличии другого идентификатора.

желаемый результат C:Scriptscontacts-trimmed.csv:

 id,first_name,last_name,email
1,john,smith,jsmith@notreal.com
2,john,smith,jsmith@notreal.com
3,sam,jones,sjones@notreal.com
3,sandy,jones,sandy@notreal.com
 

Я пробовал это с несколькими различными вариантами:

 Import-Csv C:Scriptscontacts.csv | sort first_name | Sort-Object -Property id,email -Unique | Export-Csv C:Scriptscontacts-trim.csv -NoTypeInformation
 

Любая помощь или направление будут очень признательны

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

1. Каковы правила удаления дубликатов? Т. е. почему 2-я строка не соответствует желаемому результату 2,jane,smith,jsmith@notreal.com ?

2. адрес электронной почты тот же, хотя имя другое. В принципе, может быть несколько идентификаторов и несколько электронных писем, но дубликатов электронной почты для каждого идентификатора нет. Таким образом, группа идентификаторов и адресов электронной почты должна быть уникальной.

3. Просматривая записи одну за другой, я понимаю, что вы сохраняете первую запись и отбрасываете вторую, потому что тот же идентификатор и тот же адрес электронной почты. Принимая 3-ю запись, появляется новый идентификатор, поэтому не следует ли сохранить 3-ю запись, а 4-ю отбросить?

4. Не вдаваясь в подробности… Может быть только один пользователь с адресом электронной почты, а идентификатор — студенческий билет. У многих наших родителей несколько учеников, и у нас может быть только один родитель с электронной почтой, но во многих ситуациях оба родителя используют один и тот же адрес электронной почты. Мы должны исключить один или другой, но не можем сохранить оба, поэтому я должен отсортировать по имени, чтобы при устранении дубликатов; он полностью устраняет одного из родителей и сохраняет другого, если они назначены нескольким учащимся. Надеюсь, это имеет смысл.

Ответ №1:

Вы захотите использовать Group-Object командлет, чтобы, ну, сгруппировать записи с похожими значениями:

 $records = @'
id,first_name,last_name,email
1,john,smith,jsmith@notreal.com
1,jane,smith,jsmith@notreal.com
2,jane,smith,jsmith@notreal.com
2,john,smith,jsmith@notreal.com
3,sam,jones,sjones@notreal.com
3,sandy,jones,sandy@notreal.com
'@ |ConvertFrom-Csv

# group records based on id and email column
$records |Group-Object id,email |ForEach-Object {
  # grab only the first record from each group
  $_.Group |Select-Object -First 1
} |Export-Csv .no_duplicates.csv -NoTypeInformation
 

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

1. Кстати, это приводит к тому же результату, $records | Sort-Object id, email -Unique что и . Однако это не соответствует «желаемому» результату OPs…

2. если я чего-то не упустил, приведенный выше ответ, похоже, сработал. Сейчас я проверяю вывод.

3. Он выдает 2,jane... как 2-ю строку, в то время как в OPs это «желаемый» результат 2,john... . Я думаю, что ваш вывод верен, а «желаемый» результат — нет (если я чего-то не упустил ;-)).

4. @Andy если вам нужно явно отсортировать отдельные группы, вы всегда можете изменить внутренний конвейер $_.Group |Sort-Object Name -Descending |Select-Object -First1 , например

5. @MathiasR.Jessen спасибо вам за вашу помощь. ваш код указал мне правильное направление. Я новичок в powershell и был поставлен в тупик 🙂