Я построил несколько сценариев для организации вывода данных с тестового оборудования, но я нахожусь с ментальным блокпостом с этим.Таблица сортированных данных здания с использованием hash
Испытательное оборудование контролирует четыре типа ввода (Data1, Data2, Data3, Data4) от нескольких субъектов (с идентификаторами ID1, ID2 и т. Д.) И записывает каждый из интервалов с отметкой даты и времени. CSV-файл, сбрасываемый оборудованием, организован следующим образом:
Start,Date,Time0
Subject,ID1,ID2,[...],ID#
Date,Time1
Data1,aa1,aa2,[...],aa#
Data2,ba1,ba2,[...],ba#
Data3,ca1,ca2,[...],ca#
Data4,da1,da2,[...],da#
Date,Time2
Data1,ab1,ab2,[...],ab#
Data2,bb1,bb2,[...],bb#
Data3,cb1,cb2,[...],cb#
Data4,db1,db2,[...],db#
... и так далее.
«Пуск» идентифицирует эту строку как начало данных; «Объект» идентифицирует строку как строку, содержащую идентификаторы субъекта; «Data1» - «Data4» идентифицируют строку как те, которые содержат данные для этого типа данных в определенный промежуток времени, указанный предыдущей датой и временем.
Выходные данные, таким образом, разделены на несколько блоков, что действительно является неудачным выбором со стороны производителя оборудования, особенно когда данные собираются каждые несколько минут в течение нескольких дней или недель. Для анализа данных без необходимости вручную выбирать каждый 6-й линии, необходимо сгруппировать все типы данных в блоки, например:
Data1,Subject,ID1,ID2,[...],ID#
Date,Time1,aa1,aa2,[...],aa#
Date,Time2,ab1,ab2,[...],ab#
...
Data2,Subject,ID1,ID2,[...],ID#
Date,Time1,ba1,ba2,[...],ba#
Date,Time2,bb1,bb2,[...],bb#
...
Цель состоит в том, чтобы каждый из четырех типов данных в отдельных блоках, так что временные данные для любого данного субъекта (ID1 - ID #) будут находиться в одном столбце с указанием даты и времени в качестве начальных столбцов. («DataX» и «Subject» в приведенном выше примере просто используются в качестве заголовков столбцов.)
В настоящее время я делаю это, помещая каждую строку в отдельный массив. Это был быстрый и грязный способ добиться успеха; сценарий захватывает время и дату и выталкивает строку идентификатора в каждый из четырех массивов (по одному для каждого типа данных), а затем продолжает последовательно добавлять каждую строку данных на основе типа данных. Вывод просто печатает каждый массив по строкам, добавляет пустую строку, а затем печатает следующий массив. Это работает, но в идеале я хотел бы сортировать столбцы данных по идентификатору объекта, а затем распечатывать данные, не теряя вертикальную сортировку по дате и метке времени. (Поскольку данные уже отсортированы по вертикали, в настоящее время у меня нет сортировки на массивах перед печатью.)
Каков самый простой способ сделать это? Мысленно пытаюсь разобрать, как связать данные в строке Y, колонке X с идентификатором объекта в столбце X в файле CSV. Каждый другой файл вывода данных, который я использовал, либо сохраняет идентификатор объекта как первый элемент в каждой строке, либо имеет один файл для каждого объекта, что упрощает его.
Примечание: поскольку время/дата в отдельной строке, я использую переменную для каждого; если скрипт обнаруживает строку, содержащую новое время и/или дату, она обновляет значение переменной.
Редактировать - Я включил некоторые предложения Бородина (оставляя обработку FH по строке, а не по абзацу). У меня есть данные из строки темы втягиваются в массив (@ids), и я толкая строки данных в хэш с использованием даты/времени и ID в качестве ключей:
my ($datatype, @fields) = @line;
push @keys, $datatype unless exists $data{$datatype};
my $datetime = "$date\,$time";
push @timestamps, $datetime unless exists $data{$datetime};
for my $i (0 .. $#fields) {
push @{$data{$datetime}{$ids[$i]}}=>$fields[$i]
};
Я также сбросив пары даты и время в второй массив для поддержания порядка (@timestamps). Проблема на этом этапе заключается в том, что у меня возникают проблемы с печатью значений. В настоящее время пытается:
foreach my $date (keys %data) {
print OUT $date;
foreach my $id (@ids) {
foreach my $s (keys %{$data{$date}}) {
if (exists($data{$date}{$id})) {
print OUT ",", $data{$date}{$id}
}
else {
print OUT ",";
}
}
}
print OUT "\n"; # close printing on a given date
}
Продолжайте получать вывоз мусора (печать хеш-ссылки, а не фактическое значение!).Хранитель результат выглядит следующим образом:
$VAR1 = {
'date,time' => [
'ID1' => [
'0.00'
]
'ID2' => [
'0.12',
]
'ID3' => [
'0.17',
]
'ID4' => [
'0.22',
]
]
}
};
и печатная продукция, как это:
date,time,ARRAY(0x7f91c1030f60),ARRAY(0x7f91c1030f60),ARRAY(0x7f91c1030f60),ARRAY(0x7f91c1030f60)
К сожалению примеров до сих пор были причина проблем в интерпретации. В входных файлах много лишних данных и текста, я включил только упрощенную версию частей, которые я пытаюсь извлечь и отсортировать.
Ваше описание очень неясно. Есть ли только один «Тема» для всего файла? Почему вы хотите, чтобы он повторялся четыре раза? Какие поля можно использовать в качестве ключей? например строка 'Data1' одинакова каждый раз? Является ли 'Date' фактической датой или это строка' 'Date''? Это позволило бы увидеть некоторые реальные данные, если это возможно. – Borodin
«Объект» - это первый элемент в строке в файле данных. Мой текущий скрипт использует это, чтобы распознать, что это строка, содержащая список идентификаторов. «Дата» и «Время» являются заполнителями в примере для фактической даты и временных меток. Строки для каждого из четырех типов данных одинаковы в каждом блоке данных, как указано выше, используя заполнители «Data1» через «Data4». Идентификаторы субъектов, указанные выше, были представлены как «ID1», «ID2» и т. Д. - для этого явным образом отредактируйте это. –