Из txt выбрать нужные строки и сформировать csv
Я совсем новичок. Есть желание потихоньку изучать JavaScript, через определенные задачки.
Подскажите каким путем проще сделать ниже описанную задачку (так, чтобы новичку разобраться)?. Хостинг есть. Скорее всего без php не обойтись. Подскажите куда и как копать. Есть файл txt c следующими данными: Код:
dn: uid=fimso,ou=People,dc=glories,dc=info Код:
mail: vasilevskiy.a@mail.ru В итоге хочу получить некий csv файл вида: ![]() Конечно не обязательно формировать прямо файл, достаточно вывести на экран строчки с данными и разделенные ";". Заранее всем благодарен! |
Можно разобрать, но только если файл не имеет ошибок, как например здесь - sn: Metlyaeva и sn: 12334, последнее не известно кому принадлежит.
|
Второй sn будет как мусор, ну и фиг с ним.
Сейчас дошел до следующей логики (еще не реализовал): Перебираем строки файла - в цикле запрашиваем по очередно строки (методом пост через XMLHttpRequest в php, который отдает строчку из txt), смотрим строчку, если есть "email:" отдаем остальное и ставим ";" и т.д. (нужные строчки), если встречаем пустую строчку - отдаем <br>. По идее на выходе получим что что типа: Sfvbnn@ghhn.ru;Sofia;Metlyaeva;79836967727;20160723102818Z; 12334; - это будет мусор и т.д. Изящество мне не надо, мне надо получить результат (разовая задачка и для использования только мне, не хочется в ручную лопатить 7000 строк). |
Цитата:
Паралельно хотел бы сделать через JS - повод чуть разобраться с JS (иногда появляется необходимость хоть чуть понимать что к чему). |
Rise,
Спасибо. |
Цитата:
Это делается элементарно, хоть серверным, хоть клиентским скриптом. Но коли вам надо получить "связанное", а не понять что, то должна быть строгая последовательность в данных, то есть не может встречаться очередной mail до тех пор, пока не будут получены другие поля. То есть сперва перечислены все поля одной сущности, затем другой и т.д. до конца. Посредством РНР и простым обходом массива к примеру так: $arr = []; $k = 0; foreach(file('data.txt', FILE_SKIP_EMPTY_LINES ) as $v) { if(preg_match('/mail|givenName|sn|telephoneNumber|createTimestamp/', $v)) { $v = array_map('trim', explode(':', $v)); $arr[$v[0]][$k] = $v[1]; } if(count(array_column($arr, $k))==5) $k++; } echo '<pre>'; print_r($arr); Для его выполнение требуется РНР не ниже версии 5.5. |
laimas,
Вау! Огромное спасибо!!! Сорри, а как можно вывести без ключа? ![]() |
Цитата:
|
Только для екселя ))
|
$csv = ['mail;givenName;sn;telephoneNumber;createTimestamp']; foreach(file('data.txt', FILE_SKIP_EMPTY_LINES ) as $v) { if(preg_match('/mail|givenName|sn|telephoneNumber|createTimestamp/', $v)) { $v = array_map('trim', explode(':', $v)); $arr[$v[0]] = $v[1]; } if(count($arr)==5) { $csv[] = implode(';', array_values($arr, 0)); $arr = []; continue; } } //в CSV формат $csv = implode("\r\n", $csv); //сохранем в файл, который потом можно будет скачать file_put_contents('data.csv', $csv); //либо можно сразу по запросу клиента отдавать на скачивание, не сохраняя в файл Но учитывать то о чем говорилось ранее, ибо корректность вложения по ключам в коде не проверяется. Также не проверяется последовательность ключей в исходном файле, и если последовательность может быть произвольная, то перед добавлением в массив $scv нужно будет отсортировать массив $arr по ключам. Переменная $arr не объявляется сразу, но если выключены предупреждения, то ничего страшного, главное чтобы она не была определена ранее. |
laimas,
Всё отлично. Чуть поехало, но мне это не мешает. Очень помогли. |
Что значит "поехало"?
|
В смысле чуть сместилось sn и createTimestamp, т.к. они встречаются два раза в указанном блоке. Но мне собственно и не особо мне нужны.
|
Я же говорил, что такие вещи без условий корректно практически не разобрать. Если могут быть не все ключи у каждой сущности или же для каждой из них порядок следования ключей в исходных данных будет различным, то это нужно проверять. В противном случае у одной сущности к примеру адрес будет на месте, а у другой совсем не в той ячейке.
$arr = []; //задаем нужную последовательсть заголовков $keys = ['givenName', 'mail', 'sn', 'telephoneNumber', 'createTimestamp']; //заголовок csv-файла $csv[] = implode(';', $keys); foreach(file('data.txt', FILE_SKIP_EMPTY_LINES ) as $v) { if(preg_match('/'.implode('|', $keys).'/', $v)) { $v = array_map('trim', explode(':', $v)); //если поле уже дополнено в массив, но другие поля для текущего набора не определены, то игнорируем данный набор if(array_key_exists($v[0], $arr) && count($arr) != 5) $arr = []; //иначе добавляем поле в массив else $arr[$v[0]] = $v[1]; } //если массив содержит пять полей, то добавляем в CSV if(count($arr)==5) { //отсортировать поля данных согласно csv-заголовку $arr = array_replace(array_flip($keys), $arr); //значения полей массива в CSV как csv-строку $csv[] = implode(';', $arr); $arr = []; } } //в CSV формат $csv = implode("\r\n", $csv); //сохранем в файл, который потом можно будет скачать file_put_contents('data.csv', $csv); Здесь если найдено не все пять полей, а следующая запись это одно из полей, которое уже было обнаружено, то такая запись пропускается (хотя это навскидку и по идее не будет работать всегда должным образом, то есть тут нужно нечто более сердитое). К тому же изначально задается порядок полей так, как они должны быть представлены в csv-файле. По этому же порядку происходит и сортировка данных полей не зависимо от того как они следуют в исходном файле. Ну и останется "дикое" представление времени преобразовать в человеческое. |
Всё отлично! Еще раз огромное спасибо!!!
|
Часовой пояс GMT +3, время: 04:35. |