#arrays #powershell #csv
#массивы #powershell #csv
Вопрос:
У меня есть файл экспорта CSV из системы табелей учета рабочего времени в следующем формате:
Число, сотрудник, дата, время 123,Joe Blogs,2016-07-10,08:37:29 321,Ivor Notion,2016-07-10,08:39:31 345, герр Флик,2016-07-10,08:44:05 321,Ivor Notion,2016-07-10,12:23:07 345, герр Флик, 2016-07-10,12:24:15 123, Joe Blogs,2016-07-10,13:03:49
Результат, которого я пытаюсь достичь, таков:
Число, сотрудник, Дата, время # 1, Время # 2 123, блоги Джо,2016-07-10,08:37:29,13:03:49 321, понятие Ivor,2016-07-10,08:39:31,12:23:07 345, герр Флик,2016-07-10,08:44:05,12:24:15
Я загрузил образец с:
$TimesheetData = @(Import-Csv $MergerFile)
но теперь я полностью запутался в for
циклах.
Комментарии:
1. Можете ли вы опубликовать цикл for?
2. У меня был цикл foreach, но оттуда полностью потерян сюжет. foreach ($row в $TimesheetData) { $row. Paynum $row.Employee $row. Дата $строка. Время }
Ответ №1:
Используется Group-Object
для группировки CSV-данных по сотрудникам, а затем для создания новых объектов из групп:
Import-Csv 'C:pathtoinput.csv' | Group-Object Employee | ForEach-Object {
$props = [ordered]@{
Paynum = $_.Group[0].Paynum
Employee = $_.Group[0].Employee
Date = $_.Group[0].Date
}
$i = 1
$_.Group | Select-Object -Expand Time | ForEach-Object {
$props["Time#$i"] = $_
$i
}
New-Object -Type PSObject -Property $props
} | Export-Csv 'C:pathtooutput.csv' -NoType
Если количество записей может отличаться у разных сотрудников, вам необходимо убедиться, что все созданные записи имеют одинаковое количество полей времени (или, по крайней мере, что первая запись содержит максимальное количество полей, даже если некоторые или все из них пусты), поскольку PowerShell определяет столбцы для отображения втабличный вывод с помощью первого объекта.
Вы можете определить максимальное количество временных полей из сгруппированных записей:
$csv = Import-Csv 'C:pathtoyour.csv' | Group-Object Employee
$timeCols = $csv | Select-Object -Expand Count |
Sort-Object |
Select-Object -Last 1
и используйте for
цикл для добавления столбцов времени:
$times = $_.Group | Select-Object -Expand Time
for ($i=1; $i -le $timeCols; $i ) {
$props["Time#$i"] = $times[$i]
}
Комментарии:
1. @ Ansgar Wiechers — Ваш скрипт работает отлично. Я обнаружил, что мне не нужно считать дополнительные времена, поскольку скрипт добавляет дополнительный столбец с номером «Time #» . Я нашел, добавив дополнительные элементы группы (например, Manager = $ _.Group[0].Manager ) Я могу обрабатывать любые дополнительные исходные столбцы. Единственный вопрос, который у меня есть, — как мне сгруппироваться на несколько дней, чтобы каждый день находился в отдельной строке?
2.
Group-Object Employee, Date
Ответ №2:
- Группировать по
Paynum
- Сортировка каждой группы по времени
- Возьмите первый элемент в группе
- Удалить
Time
- Добавить
Time#1
= время первого элемента иTime#2
= время второго элемента
$merged = Import-Csv r:1.csv |
Group Paynum |
ForEach {
$sorted = $_.Group | Sort Time
$sorted[0] |
Select * -ExcludeProperty Time |
Select *,
@{N='Time#1'; E={$sorted[0].Time}},
@{N='Time#2'; E={$sorted[1].Time}}
}
$merged | Export-Csv r:2.csv -NoTypeInformation
Комментарии:
1. ваш сценарий работает отлично, но альтернатива немного более гибкая, поскольку стойки ворот теперь перемещены — тем не менее, спасибо за помощь.