Страницы: 1 2 3 4 След.
RSS
Поиск в файле csv, не открывая его
 
Дoбpый дeнь.
Ищeтcя cпocoб, кoтopый пoзвoляeт пpoизвoдить пoиcк в фaйлaх csv, кoтopыe нa мoмeнт пoиcкa НE OТКPЫТЫ В EXCEL и нaхoдятcя в пaпкe пo oпpeдeлeннoму пути, нaпpимep C:\folder\file.csv.
Пpичинa тaкoгo экзoтичecкoгo cпocoбa пoиcкa зaключaeтcя в тoм, чтo кaждый из csv-фaйлoв имeют OГPOМНЫЙ PAЗМEP (oт 150 Мб дo нecкoльких ГБ) ввиду бoльшoгo чиcлa cтpoк. И ecли нужнo нaйти ячeйку c oпpeдeлeнным знaчeниeм (oнo уникaльнo, пpиcутcтвуeт тoлькo в oднoм из этих фaйлoв в пaпкe), нужнo пo пpивычкe oткpывaть пocлeдoвaтeльнo кaждый фaйл и вpучную пpoизвoдить пoиcк пo дaннoму уникaльнoму знaчeнию.
Вoзмoжнo, cитуaцию упpoщaeт тoт фaкт, чтo иcкoмoe уникaльнoe знaчeниe вceгдa будeт нaхoдитьcя в 12-oм пo cчeту cтoлбцу тaблицы (cтoлбeц L). Пo cути нужнo пocлeдoвaтeльнo пpocкaниpoвaть 12-ый cтoлбeц (cтoлбeц L) нa пpeдмeт cooтвeтcтвия нужнoму идeнтификaтopу (этo нaбop иcключитeльнo лaтинcких букв и цифp, бeз пpoбeлoв, никaких cпeцcимвoлoв).
Нo зaдaть идeнтификaтop для пoиcкa нужнo явным oбpaзoм (т.e. уcлoвнo ASD123FGH456) и кaк-тo нaтpaвить нa фaйлы пaпки. Дaжe ecли пoиcк пo вceм фaйлaм пaпки cдeлaть будeт тpуднo, дocтaтoчнo cдeлaть для oднoгo фaйлa, имя для дpугих фaйлoв я гoтoв мeнять кaждый paз вpучную.
Peзультaт тaкoгo пoиcкa в идeaльнoм cлучae дoлжeн быть тaким: вывoд вceх знaчeний из cтpoки тaблицы, в кoтopoй пpиcутcтвуeт идeнтификaтop. Нa кpaйний cлучaй дocтaтoчнo будeт вывoдa имeни csv-фaйлa, гдe тaкoe coвпaдeниe будeт нaйдeнo. Тoгдa я вpучную oткpoю этoт фaйл в экceль и нaйду cпepвa caмo coвпaдeниe, a пoтoм cкoпиpую вcю cтpoчку для дaльнeйшeй paбoты.
Мoжeт ктo-нибудь пoмoчь? Пpeдпoлoжу, чтo этo дeлaeтcя мaкpocoм. Либo кaк-тo инaчe (либo кaким-нибудь sql-зaпpocoм). Нo я нe знaю cпocoбa этoт пpoцecc aвтoмaтизиpoвaть.
Пpимep тaблицы пpиклaдывaю.
Зapaнee cпacибo.
 
csv это текстовой файл и работать с ним можно как с текстовым файлом
если файл огромный считывать блоками. Разбивать на массив строк
А дальше два варианта. Либо разбивать строку на элементы и потом проверять 12 колонку. Либо просто проверять наличие в строке
Ели нашлось дальше не обрабатывать. Сразу выводить строку
 
Вам в помощь пример работы через sql запрос.
Файл схема должен быть в папке с csv файлами, в нем надо описать поля.
В этом файле прописано, что заголовков полей нет
Код
Sub readCsv()
    TempPath = "Папка в которой находятся файлы csv и файл схемы"
    namned = "6.csv" ' имя файла
    sCon = "Driver={Microsoft Text driver (*.txt; *.csv)};DBQ=" & TempPath & ";DriverId=27;MaxBufferSize=2048;PageTimeout=5"
    Set Cn = CreateObject("ADODB.Connection")
    Cn.Open (sCon)
    sSql = " select  F1,F2,F3,F4,sum(F5),sum(F6)  from [" & namned & "] group by F1,F2,F3,F4"
    Set rs = CreateObject("ADODB.Recordset")
    rs.Open sSql, Cn, 3, 1
    If rs.RecordCount = 0 Then
        rs.Close
        rs = Nothing
        Cn = Nothing
        Exit Sub
    End If
    res = rs.getrows
        rs = Nothing
        Cn = Nothing
End Sub
 
Вообще неплохо бы знать задачу...
Например если задача такая - нужно периодически (не важно как часто) искать какое-то одно значение, этих файлов много, но они неизменны, только раз в месяц приходит по одному новому.
Я бы составил список этих значений с точными адресами, например хоть в отдельном текстовом файле, можно тоже csv, и дополнял его с приходом нового файла. Не особо сложная задача.
Затем искал кодом по этому файлу, далее уже извлекал именно ту строку того файла, которая в прописана в этом индексном.
Если памяти эта информация занимает не критично много - можно в начале работы загрузить этот индексный в словарь, и таким образом далее не тратить время на поиск в индексном, а сразу из словаря брать точные координаты данных.
Изменено: Hugo - 17.05.2020 12:03:13
 
Александр Моторин
Спасибо. Это один из принципов, как может быть реализовано решение. Полагаю, что техническая сторона реализации содержится в ответе doober
doober
Помогите, пожалуйста, с пониманием того, как работает Ваш способ.
Текст приведенного макроса уже готовый или его нужно переписывать под мою задачу? В VBA не разбираюсь, поэтому задаю такой глупый вопрос.
Мне нужно подставить путь расположения своих файлов. Т.е. нужно задать следующее:
TempPath = " C:\folder\"
Далее в папку положить файл schema.ini. Вижу, что в ini-файле есть повторяющаяся структура. Нужно вставить названия своих csv-файлов и добавить их необходимое количество.
А вот по структуре как понять, что означают поля (т.е. каждая строчка)? Эти строчки как-то нужно корректировать или можно оставить без изменений?
[1.csv]
ColNameHeader=False
Format=Delimited(;)
MaxScanRows=0
CharacterSet=ANSI
Col1=F1 Char Width 255
Col2=F2 Char Width 255
Col3=F3 Char Width 255
Col4=F4 Char Width 255
Col5=F5 Float
Col6=F6 Float
Ну и самое главное, как выполнить sql-запрос? Он выполняется из макроса?
Hugo
Файлы не меняются, равно как и значения в них. Поиск будет выполняться не часто, 10-20 раз в день, а иногда меньше. Учитывая размер файлов, размер индекса будет огромным, зависание будет 100%.
Как вариант, можно натравить на эти файлы программы для построения индекса, например, Архивариус3000. И потом при помощи программы искать.
Но я подумал, что может быть существуют более изящные способы поиска.
 
Я посмотрел сколько места занимает текстовый файл с 1048576 строками с этим артикулом, именем файла и условно номером строки - получается 27,0 МБ (28 311 552 байт), в зипе 68,0 КБ (69 632 байт).
В xlsb - 2,86 МБ (3 002 368 байт), но тут уже в один столбец всё не запишешь, но можно использовать и вширь...
Думаю каких миллионов так 10 таких индексов вполне реально пользовать,
Я вообще я на практике всё это загрузил бы в Qlik, при появлении новых данных можно легко обновить модель. Это конечно если пользуетесь. Не знаю, может и в PBI можно быстро такое ворочать.
Вообще простой поиск по содержимому файлов делает ведь и система, и Тотал, и помню как-то юзал какую-то утилиту, которая сразу и строку выводила, и в архивах тоже умела искать. Но не уверен что такие объёмы потянет... Название не помню.
Изменено: Hugo - 17.05.2020 17:56:12
 
excel_and  Вы бы файлик csv оригинал на 20-30 строк  прикрепили, тогда бы и я что то смог подсказать
 
Не думаю, что Excel самый подходящий инструмент для поиска текста в файлах. Из того, что у меня есть, с этим хорошо справляeтся Far Manager (Alt+F7). Поиск слова в массиве текстовых файлов общим размером в 25 ГБ занимает меньше 1 минуты.
Владимир
 
У меня была утилита попроще, да и файлы были маленькие, хоть и много. Но вот например http://docfetcher.sourceforge.net/ru/index.html не подойдёт?
P.S. Не, что-то docfetcher плохо тянет даже этот миллион...
Изменено: Hugo - 17.05.2020 20:49:04
 
Hugo
В папке порядка 100 файлов, суммарный размер файлов – около 30 Гб. Смущают 2 файла с самыми большими размерами: 10 Гб и 1,2 Гб.
Я хочу попробовать рекомендуемый  DocFetcher. По результату отпишусь.
С Qlik не знаком. Подскажите, пожалуйста, ссылку. Если инструмент помогает при работе с тяжелыми файлами, то это в любом случае будет полезно для общего развития.
doober
Отлично. Пример файла приложу. Но в исходном виде не смогу это сделать, т.к. в нем содержатся персональные данные. Но могу просто внести в ячейки другие значения, думаю, это никак не повлияет на суть задачи.
sokol92
Far имею в виду как дополнительный софт.
Общий принцип таков, чтобы метод не предполагал использования стороннего софта. Здесь ограничения лишь в том, что на работе никто этот софт не позволит установить ни при каких обстоятельствах. А решать задачу поиска необходимо в т.ч. на рабочем ПК, где есть MS Office и возможность выполнять макросы на VBA. Но офис сильно тормозит при открытии тяжелых файлов и очень желательно хоть чуть-чуть автоматизировать процесс, минуя зависание ПК, которое делает невозможным работу.
 
DocFetcher я себе поставил для проверки. Так себе... CSV по умолчанию не видит, но можно научить.
Плохо то, что из строки ищет только слово целиком, что в случае с csv редко когда годится. Но можно использовать символы подстановки, только нужно не забыть :(
И на предпросмотр выгружает весь файл, а не только найденную строку - по этому параметру точно не годится для огромных файлов.
QlikView/Qlik Sense - это бизнес-аналитика, платная штука. Sense правда была домашняя бесплатная версия, но вроде как этим летом обещали закрыть (без сети не работает).
Если нет - то и не парьтесь. Но если нет вообще таких программ в бизнесе - советую задуматься.
Изменено: Hugo - 17.05.2020 21:21:17
 
Цитата
excel_and написал:
иcкoмoe уникaльнoe знaчeниe вceгдa будeт нaхoдитьcя в 12-oм пo cчeту cтoлбцу тaблицы (cтoлбeц L). Пo cути нужнo пocлeдoвaтeльнo пpocкaниpoвaть 12-ый cтoлбeц (cтoлбeц L) нa пpeдмeт cooтвeтcтвия нужнoму идeнтификaтopу (этo нaбop иcключитeльнo лaтинcких букв и цифp, бeз пpoбeлoв, никaких cпeцcимвoлoв)..  ...Peзультaт тaкoгo пoиcкa в идeaльнoм cлучae дoлжeн быть тaким: вывoд вceх знaчeний из cтpoки тaблицы, в кoтopoй пpиcутcтвуeт идeнтификaтop. Нa кpaйний cлучaй дocтaтoчнo будeт вывoдa имeни csv-фaйлa, гдe тaкoe coвпaдeниe будeт нaйдeнo. Тoгдa я вpучную oткpoю этoт фaйл в экceль и нaйду cпepвa caмo coвпaдeниe, a пoтoм cкoпиpую вcю cтpoчку для дaльнeйшeй paбoты.
А чем это предложение не подходит?
Цитата
Hugo написал:
Я бы составил список этих значений с точными адресами, например хоть в отдельном текстовом файле, можно тоже csv, и дополнял его с приходом нового файла. Не особо сложная задача.
Со всех файлов собрать 12-ые столбцы в одном файле (уже вес полегчает) и в нем искать. Далее по крайнему случаю
 
Вообще да, можно для начала просто скопировать эти столбцы на один лист. Тогда поиском можно сразу определить и файл, и даже строку, хотя знание строки может пригодиться только если скормить это макросу, чтоб он её выдёргивал из текста.
Если конечно влезет на лист. А копировать в текст - гемор, если вручную, даже наверное невозможно. Скриптом можно.
Изменено: Hugo - 17.05.2020 21:45:50
 
Hugo
Михаил Л
DocFetcher скачал себе сперва портабельную. Запуститься отказалась.Скачал установщик. Установленный вариант тоже не запустился. Посмотрел через Dependency Walker: оказывается, программа не совместима с моей Win 8.1 x64. На виртуальной машине запускать не стал, т.к. это заметная потрея производительности. Потом увидел Ваш комментарий по поводу csv-файлов.
Ради интереса запустил создание индекса в Архивариус3000. Создание индекса 5% от всего объема занимает 13 минут. Т.е. индексировать будет долго, да и тормоза конкретные. Но я дождусь и проверю, как работает поиск.
По поводу работы исключительно с 12-ым столбом. Это - идея. Но скопировать вручную 12-ый столбец я смогу со всех файлов, кроме 2-ух очень тяжелых. На них даже проверять лишний раз не хочу, т.к. система зависает наглухо и просто приходится перезагружать компьютер. Ни один из 2-ух этих тяжелых файлов у меня так и не открылся в эксель, т.к. банально не хватает памяти. Т.е. что-то где-то крутиться, но результат, видимо, придется ждать очень долго. Я ждал 1 час, но ничего так и не открылось. Плюнул и перезагрузил.
А вот можно ли скриптом (макросом) считать весь 12-ый столбец из каждого файла и получить сотню файлов с данными только 12-го столбца. Это уже будет что-то. Но, повторюсь, сделать это нужно без открытия исходных csv-файлов (помня об ограничении с 2-мя очень тяжелыми файлами). А потом по аналогии считать все остальные столбцы из найденного csv слева и справа от 12-го столбца (для случая с тяжелыми файлами более 1 Гб) или вообще всю строчку.
 
Как вариант - простой скрипт, из моих 28 МБ выбрал второй столбец за 28 секунд, можете попробовать на чём-то небольшом. В коде изменить пути и названия файлов.
Ну и конечно 1 поменять на 11 - для 12-го столбца. Но смотрите какой там у Вас разделитель - у меня ";"
В конце будет месиджбокс с потраченным временем.
Отследить что работа делается можно в процессах- у меня Wscript отъедал 40% процессора.
Вот правда не знаю какие лимиты по объёмам обрабатываемых файлов, я с большими не работал.
Изменено: Hugo - 18.05.2020 00:15:35
 
Hugo
Мой опыт с Архивариус3000 следующий:
Размер индекса 10,35 Гб
Время индексирования 02:05:46
Не удалось проиндексировать 2 файла.

Что касается файлов, которые не проиндексированы. Это как раз 2 тяжелых файла: 1-ый с размером 1,2 Гб, 2-ой с размером 10 Гб.
Поиск вроде бы работает (проверял очень бегло всего не нескольким идентификаторам).

Ваш скрипт скорректировал под себя.
Прогнал на среднего размера файлах, 130-150 Мб. Скорость отработки от 50 сек. Заметил, что в исходном файле и в файле с выборкой получается разное количество строк. Думаю, что нужно смотреть в сторону пустых ячеек, они где-то встречаются. Детально буду смотреть завтра.
По поводу тяжелого файла с размером 1,2 Гб. Натравил на него скрипт. Скрипт отработал без проблем, время выполнения 446,6396. Далее открыл файл с выборкой в Excel и увидел сообщение, что файл загружен не полностью. Excel загрузил 1 048 576 строк. Решил открыть файл в LibreOffice, но и в нем присутствует то же самое ограничение на 1 048 576 строк.
В свете имеющихся ограничений на число строк возник еще один вопрос: можно ли один тяжелый csv-файл точно так же разбить с помощью скрипта на несколько файлов с произвольным числом строк, например на 500 000 строк (это соответствует моим размерам файла примерно в 110-115 Мб), сохранив его структуру? Т.е. первые 500 000 строк в 1-ом файле, далее следующие 500 000 строк во втором файле и т.д.). Так можно будет отработать два оставшихся файла в 1,2 Гб и 10 Гб.

Завтра также попробую запустить скрипт на файле в 10 Гб. Мне кажется, должно получиться, хотя не совсем уверен.
Заранее спасибо.
 
Разбить конечно можно.
А открыть эти "длинные" файлы можно пробовать например в notepad++ - мой с 1 048 577 строк открывает без проблем и за секунду (в моём примере ещё одна пустая строка есть).
Вот на скору руку добавил разбивку. Легко изменить чтоб выбирало один столбец (это был первоначальный вариант, и там есть закомментированная проверка что пишутся все считанные строки):
Скрытый текст

P.S. Если нужна индикация процесса - можно этот код вот прямо как есть "положить" в Sub в Эксель, тогда можно приладить статусбар, куда выводить например каждое 100000 значение счётчика. Чуть притормозит процесс.
Ну и тогда можно нарастить код - добавить выбор обрабатываемого файла, или сделать обработку сразу многих, чтоб запустить например на ночь, или планировщиком рано утром.
Изменено: Hugo - 18.05.2020 10:37:10
 
Можно было бы написать программку, с хорошей скоростью, но... Жаль, не смогу поучаствовать, нет времени совсем..
«Бритва Оккама» или «Принцип Калашникова»?
 
Проверил вот эту программу:
https://forum.ixbt.com/post.cgi?id=attach:23:40715:19:1.rar
страница https://forum.ixbt.com/topic.cgi?id=23:40715
Режет и csv, и довольно быстро, но если исходный файл заканчивается без перевода строки - то выкидывает ошибку и последняя строка пропадает!
Думаю можно ещё что-нибудь годное нарыть.
Вот например тут что-то на PowerShell: https://stackoverflow.com/questions/1001776/how-can-i-split-a-text-file-using-powershell
Изменено: Hugo - 18.05.2020 13:37:20
 
Цитата
excel_and написал:
никто этот софт не позволит установить ни при каких обстоятельствах
Есть уже установленная программа (утилита командной строки) от разработчика Windows (работает медленнее, чем Far). Пример (в условиях #1):

Find "ASD123FGH456" C:\folder\*.csv
Изменено: sokol92 - 18.05.2020 15:16:39
Владимир
 
Да, стандартный поиск тоже что-то ищет, и даже обиделся что непроиндексировано (т.е. можно создать индекс), но - нашёл искомое только в маленьких кусках что я резал из целого, а два этих больших исходника (условно больших - всего 28МБ)проигнорировал :(
 
excel_and, можно загрузить весь ваш массив в модель данных и вытаскивать нужную строку фильтром сводной таблицы. Если данные пополняются, то обновление массива в файле будет занимать долгое время (т.к. в модель данных нельзя добавлять значения порциями, только обновление всего массива целиком. Зато выбор строки по фильтру происходит сравнительно быстро.
Для примера загружал таким макаром справочник соответствия каталожных номеров автозапчастей оригинал/аналог на 60 млн строк 8 столбцов. Файлик получился на 1Гб, обновление данных в нем около 40 минут, зато поиск через фильтр сводной таблицы происходит очень быстро, т.к. в основе модели данных лежит движок БД. Но оперативки надо МНОГО.  :D
Изменено: PooHkrd - 18.05.2020 16:46:04
Вот горшок пустой, он предмет простой...
 
Hugo
Ваш скрипт по разбиению файлов на части по 500 000 строк применил.
На файле 1,2 Гб отработал за 375,739 сек = 6,26 мин. Потом применил на файле в 10 Гб, где он отработал за 3892,195 сек = 64,87 мин. Это отличный результат, т.е. с большими файлами работает.
Далее я начал потихоньку руками извлекать столбцы с нужным идентификатором. Как только получу все эти столбцы, добавлю в индекс Архивариус3000. Думаю, все должно работать. Таким образом, для дома найден сложный и затратный вариант решения проблемы. Делается хоть и долго и через задницу, но тем не менее :)
Рано или поздно Windows добавит содержимое этих файлов (со столбцами с идентификаторами) в свой индекс. Хотя конечно производительность крайне низкая...
Рекомендованные программы для резки и скрипт на powershell обязательно посмотрю.
sokol92
find тоже попробовал. Пришлась очень кстати. Действительно ищет, но при таких объемах результат приходится ждать довольно долго (ибо сканирует каждый файл заново, без возможностей искать при помощи индексирования). Хотя с задачей справляется. Наверное, буду пользоваться ей на рабочем ПК. Пока это тоже вариант.

bedvit
Если вдруг будет время и желание, польза будет неоценимая (особенно, если будут использоваться штатные средства винды и стандартного офиса).
Пока продолжаю экспериментировать, результаты напишу.
Заранее спасибо.
 
Цитата
excel_and написал:
Потом применил на файле в 10 Гб, где он отработал
Если не секрет, сколько файлов по 500000 строк получилось из файла объемом 10 Гб?
 
Михаил Л
Не секрет. Из одного файла в 10 Гб получилось 116 файлов, каждый из которых (кроме последнего) имеет 500 000 строк. В каждом из файлов - 26 столбцов.
Изменено: excel_and - 18.05.2020 17:16:37
 
Цитата
excel_and написал:
Далее я начал потихоньку руками извлекать столбцы с нужным идентификатором
- так в том же коде я оставил этот функционал - можно из тех же исходников нагенерить файлов по 500000 строк только с этим столбцом.
 
excel_and, не знаю потянет или нет, можно б попробовать и Power Query применить
 
Hugo
Блин, я протупил :) Но буду знать :) Ничего страшного.

Где (1) нужно поменять на (11)?

objFile.WriteLine strNextLine 'Split(strNextLine, ";")(1) '& " = " & pr

-------

Нет, я оказывается все так и сделал. Т.е. извлекал 12 столбец по первому скрипту из файлов, которые резались по 500 000 строк по второму скрипту. Или вы имели в виду, что второй скрипт, который режет, также позволяет еще и извлекать определенные столбцы? Т.е. одним действием можно сделать то, что я сделал за 2 действия?

Изменено: excel_and - 18.05.2020 17:41:17
 
Нужно так:
Код
objFile.WriteLine Split(strNextLine, ";")(11)

Но это если разделитель полей ;
Иногда бывает иначе.
Там две такие строки в коде.
Изменено: Hugo - 18.05.2020 17:39:53
 
Михаил Л
Power Ouery готов установить и протестировать, но никогда им не пользовался.
Изменено: excel_and - 18.05.2020 17:41:55
Страницы: 1 2 3 4 След.
Наверх