2012-02-14 3 views
2

Прежде всего, я очень новичок в Powershell, и я хотел бы поблагодарить всех участников этого сайта за помощь в предоставлении ответов на разные четыре месяца! Из-за этого сайта я многое сделал за короткое время!Powershell: Сортировка/Удаление дубликатов в CSV-файле

Вот и проблема, и я сделаю все возможное, чтобы объяснить. У меня есть файл CSV для создания учетных записей учащихся. Наша система управления студентами выпускает запись каждый раз, когда студент регистрируется, изменяется или выходит из программы. Если этот ученик «пробует» несколько разных программ, у них будет несколько записей в CSV-файле. Поэтому моя цель - сортировать CSV-файл по идентификатору пользователя (userID никогда не изменяется) и CurrentStatusDate (который был когда запись была создана). С помощью этой команды:

Import-CSV "C:\students.csv" | sort UserID,CurrentStatusDate 

Образца CSV записей:

"UserID","AccountStatus","PersonID","PIN","FirstName","LastName","IDEXPIRY","Term","Role","Course","SectionName","locationDescription","Location","CurrentStatusDate" 
"aboggs","Add","xxxxxxx","xxxxxxx","Ashley","Baggs","5/11/2013","xxxxxx","Student","Accounting Technology","xxxxxx","xxxxxx","xxxxxx","9/12/2011" 
"aboutilier","Add","xxxxxxx","xxxxxxx","Amelia","Boutilier","5/3/2012","xxxxxx","Student","Adult Education","xxxxxx","xxxxxx","xxxxxx","11/15/2011" 
"abowtle","Delete","xxxxxxx","xxxxxxx","Aleisha","Bowtle","7/31/2013","xxxxxx","Student","Business Administration","xxxxxx","xxxxxx","xxxxxx","2/1/2011" 
"abowtle","Add","xxxxxxx","xxxxxxx","Aleisha","Bowtle","7/31/2012","xxxxxx","Student","General Studies","xxxxxx","xxxxxx","xxxxxx","9/9/2011" 
"abradley","Delete","xxxxxxx","xxxxxxx","Anna","Bradley","10/25/2011","xxxxxx","Student","Adult Education","xxxxxx","xxxxxx","xxxxxx","11/17/2011" 
"abridges","Delete","xxxxxxx","xxxxxxx","Ashley","Bridges","10/5/2011","xxxxxx","Student","Adult Education","xxxxxx","xxxxxx","xxxxxx","11/15/2011" 
"abrown10165","Add","xxxxxxx","xxxxxxx","Adam","Brown","10/28/2011","xxxxxx","Student","Advanced Firefighting STCW VI/3","xxxxxx","xxxxxx","xxxxxx","10/24/2011" 
"abrown10165","Add","xxxxxxx","xxxxxxx","Adam","Brown","12/16/2011","xxxxxx","Student","Simulated Electronic Navigation Level 1, Part B","xxxxxx","xxxxxx","xxxxxx","11/10/2011" 
"abrown8081","Add","xxxxxxx","xxxxxxx","Alex","Brown","5/25/2013","xxxxxx","Student","Culinary Arts","xxxxxx","xxxxxx","xxxxxx","9/6/2011" 
"abrown8950","Delete","xxxxxxx","xxxxxxx","Ashley","Brown","9/13/2012","xxxxxx","Student","Medical Support Services","xxxxxx","xxxxxx","xxxxxx","9/14/2011" 
"acameron2637","Delete","xxxxxxx","xxxxxxx","Anne","Cameron","10/14/2011","xxxxxx","Student","Adult Education","xxxxxx","xxxxxx","xxxxxx","10/14/2011" 
"acameron4368","Add","xxxxxxx","xxxxxxx","Amanda","Cameron","4/20/2013","xxxxxx","Student","Applied Degree in Culinary Operations","xxxxxx","xxxxxx","xxxxxx","10/12/2011" 
"acampbell10266","Add","xxxxxxx","xxxxxxx","Amanda","Campbell","5/4/2012","xxxxxx","Student","Adult Education","xxxxxx","xxxxxx","xxxxxx","11/7/2011" 
"acampbell6499","Delete","xxxxxxx","xxxxxxx","Aaron","Campbell","10/31/2012","xxxxxx","Student","Retail Business Management","xxxxxx","xxxxxx","xxxxxx","11/1/2011" 
"acampbell6499","Add","xxxxxxx","xxxxxxx","Aaron","Campbell","12/13/2011","xxxxxx","Student","Complete the Accounting Cycle - Part II","xxxxxx","xxxxxx","xxxxxx","9/26/2011" 

Это должно группы всех идентов с теми же записями, а затем отсортировать их по дате создания. Затем я хочу удалить дубликаты и сохранить созданную последнюю запись. Я знаком с -Unique, но это не относится к команде выше, поскольку она удалит только записи, которые имеют дубликат userID и CurrentStatusDates.

Если бы «Google-ing» и ударил головой в течение 2 дней ... начинаю думать, что нет «легкого» ответа, но мой программирование-fu слаб ... Просто ища «подталкивание» в в правильном направлении.

Спасибо!

Chris

+0

Если вы могли бы разместить образец ввода и показать ожидаемый выход, это поможет. –

+0

Конечно, Энди, извините ... Мне следовало бы опубликовать некоторые строки из csv ... Я обновил свое оригинальное сообщение – ca269

ответ

2

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

Import-CSV "C:\students.csv" | Group-Object userid | foreach-object { $_.group | sort-object currentstatusdate | select -last 1} 

Подобно тому, как вы описываете - мы объединяем по идентификатору, а затем сортировать по CurrentStatusDate, а затем выбрать наиболее последние записи. Я не уверен, как CurrentStatusDate отформатирован, поэтому я не знаю, будет ли прямой sort-объект достаточно хорошим.

+0

Спасибо, riknik, я обновил свое оригинальное сообщение с образцом из csv. Любите свой код snipit, я попробую его и дам вам знать .. – ca269

+0

Работал отлично! Не уверен, кто благодарит вас больше ... вмятины в стене или вмятины в голове! – ca269

+0

Как говорит мюлинер в своем ответе, остерегайтесь того, как сортируются даты. В приведенном выше примере они сортируются в алфавитном порядке, а не в знании того, как работают даты. Поскольку вы работаете с датами календаря, а не с датой + времени, вы можете уйти от него, в противном случае это решение нуждается в некоторой настройке, чтобы изменить бит sort-object. –

0

Как насчет:

  • присоединения поля вместе (http://www.johndcook.com/PowerShellCookbook.html#a19) на
  • разделителя
  • использовать уникальный
  • split
+0

Не уверен, что это сработает в моем случае ... если бы оба поля были и тогда не было бы дубликатов для уникального процесса ... но ... Я не знал, что вы могли бы это сделать, поэтому теперь я узнал что-то еще для будущих задач! Спасибо Chriseyre2000 – ca269

0

Не тестировалось:

$new_csv = @() 
Import-CSV "C:\students.csv" | sort UserID | 
    foreach { 
    if ($temp -eq $null){$temp = $_} 
    if ($_.UserID -ne $temp.UserID){ 
     $new_csv += $temp 
     $temp = $_ 
     } 
elseif ([datetime]$_.CurrentStatusDate -gt [datetime]$temp.CurrentStatusDate){ 
    $temp = $_ 
    } 
} 
$new_csv += $temp 
export-csv $new_csv c:\somedir\new_csv.csv -notype 

Когда первая запись проступает, $ температура будет приготовьтесь к этой записи. По мере прохождения каждой новой записи, если это для одного и того же идентификатора студента, метка времени проверяется снова на запись в $ temp. Если он новее, он попадает в $ temp. Когда он видит изменение userID, он пишет $ temp (который должен теперь соответствовать последней записи для последнего пользователя) $ new_csv. Затем он устанавливает $ temp в текущую запись и начинается с следующего идентификатора пользователя. Так как он не увидит изменения для пользователя для последней учетной записи, вы должны выбрать его после завершения цикла, а затем экспортировать csv.

Не уверен, какой формат имеет временная метка, но я предполагаю, что он правильно проанализирует значение [datetime]. Но если он исходит из .csv, это будет строка, и казалось маловероятным, что она сортировала бы в порядке datetime в строковой сортировке, поэтому я даже не потрудился.

+0

Wow mjolinor, красивый код! Поскольку я новичок в этом, я не против сказать, что я понятия не имею, что это значит/делает ... но я обещаю вам, что я узнаю ... Это такой код, который я изучаю много от! Я проверю все, что смогу, и вернусь к вам! – ca269

+0

@mjolinor - «continue» не делает то, что вы думаете в блоке foreach-object. – x0n

+0

Спасибо. Я пропустил это. Он может обойтись без него. Что-нибудь еще не так? – mjolinor

Смежные вопросы