Показать полную графическую версию : Разбить тхт файл не только по строкам, но и по папкам
Abricosio
11-07-2018, 15:15
В замечательной теме (http://forum.oszone.net/post-1961186.html) раскрывается вопрос, как разбить большой тхт файл на много мелких по кол-ву строк
Моя задача чуть шире. Есть файл на 10 млн строк. Мне нужно получить 100 папок, в каждой по 100 файлов тхт, в каждом файле по 1000 строк из стартового файла.
Названия папок 1,2,3,4,5,...,100
Названия файлов 1.txt, 2.txt, 3.txt, ..., 100.txt
Кто-нибудь может помочь с этой непосильной для меня задачей?
Кто-нибудь может помочь с этой непосильной для меня задачей? »
CMD тут вряд ли поможет... 10 млн. строк... подавится считать... :)
Лучше вооружитесь powershell-ом.
Abricosio
11-07-2018, 15:32
А как powershellом это сделать? :)
Abricosio, размер файла:
Есть файл на 10 млн строк. »
каков? В мегабайтах?
как powershellом это сделать? »
просто по файлам раскидать вот так:
$counter = 0; $linesPerFile=10000; Get-Content .\big.log | ForEach-Object { $counter++; Add-Content -Path "$(($counter/$linesPerFile).ToString('000000')).log" -Value $_ }
к сожалению, в реализации Add-Content Микрософт накосипорила - директории он автоматически не создаёт, поэтому коротко не написать :(
После Get-Content указываете путь к файлу, в текущей директории создаются файлы по 10 тыс строк (количество задаётся переменной $linesPerFile)
размер файла:
каков? В мегабайтах? »
это неважно, не требуется никакого хитрого анализа, чтобы его его целиком в память пихать
А как powershellом это сделать? »
Как-то так:
$fl = 'test.txt'
$root = 'root'
if (!(test-path $root)){md $root|out-null}
gc $fl -read 1000|%{$i,$n=1,1}{
$tmp = "$root\$n"
if(!(test-path $tmp)){md $tmp|out-null}
set-content -path "$tmp\$i.txt" -val $_
switch ($i) {
100 {$n++;$i=0}
}
$i++
}
чтобы его его целиком в память пихать »
если его целиком пихать в память, powershell загнется не хуже (или не лучше?) cmd :)
если его целиком пихать в память, powershell загнется не хуже (или не лучше?) cmd »
и сам делаешь то же самое: если пользователь решит делить файл не на 100 тыс. файлов, а на два? - всё переписывать?
и сам делаешь то же самое »
где? присмотрись повнимательнее...
Разве что, можно чуток оптимизировать, чтобы не дергать $tmp при каждой итерации:
$fl = 'test.txt'
$root = 'root'
if (!(test-path $root)){md $root|out-null}
gc $fl -read 1000|%{$i,$n=1,1;$tmp = "$root\$n"}{
if(!(test-path $tmp)){md $tmp|out-null}
set-content -path "$tmp\$i.txt" -val $_
switch ($i) {
100 {$n++;$i=0;$tmp = "$root\$n"}
}
$i++
}
это неважно, не требуется никакого хитрого анализа, чтобы его его целиком в память пихать »
Э… Ну, запихните в память текстовый файл в десять-двадцать гигабайт.
где? »
результирующий файл формируется в памяти и за раз пишется инструкцией set-content
Ну, запихните в память текстовый файл в десять-двадцать гигабайт. »
зачем?
результирующий файл формируется в памяти и за раз пишется инструкцией set-content »
И что? Я говорю о:
gc text.txt
и
gc text.txt -readcount 1000
В первом случае, по конвейеру будет передаваться первая строка только после помещения всего файла в память (что может привести к достаточно длительному ожиданию, если не зависанию, при достаточно большом файле). Во втором случае, первая строка (вернее блок строк) передается после помещения в память некоторого количества строк -readcount <int64>, что значительно ускоряет процесс... в общем, попробуйте, тогда станет понятно в чем разница.
зачем? »
Затем, что не поместится.
Abricosio
11-07-2018, 22:00
Все отлично в примере на павершел, один только нюанс - пустая строчка в самом конце, но я ее регуляркой почикаю) Спасибо!
YuS_2, неверно
по умолчанию readcount равно единице, чтобы прочитать весь файл за раз нужно принудительно выставить нуль
Вы смешали в одно "буфер чтения" и размер выходного файла. Всё это "значительно ускоряет процесс" пока файлы крохотные. А как только понадобится напилить файл на куски по несколько ГБ (например, чтобы на DVD записать) - так сразу скрипту и поплохеет.
Busla, YuS_2, в документации сказано, что:
-ReadCount <Int64>
Specifies how many lines of content are sent through the pipeline at a time. The default value is 1. A value of 0 (zero) sends all of the content at one time.
This parameter does not change the content displayed, but it does affect the time it takes to display the content. As the value of ReadCount increases, the time it takes to return the first line increases, but the total time for the operation decreases. This can make a perceptible difference in very large items.
но ничего не сказано про собственно само чтение. Как с этим обстоит дело?
Abricosio
11-07-2018, 22:38
А нет, не получается, регуляркой эту строку не видно, удалить массово через notepad++ не получается. Возможно ли переделать скрипт, чтобы он не делал 1001-ю пустую строку?
Заранее большое спасибо!
Abricosio, там нет «пустой строки»:
https://i.imgur.com/nClHTbb.png
где Вы её нашли?!
Abricosio
11-07-2018, 23:04
Странно, у меня во всех файлах последняя строка пустая, 1001я. Проверял в notepad++ и обычном тхт редакторе
Abricosio, это:
https://i.imgur.com/nnKcpS4.png
не «пустая строка».
Пустая строка — вот:
https://i.imgur.com/6rGzKIY.png
Если Вам категорически нужно, чтобы последняя строка не завершалась символами конца строки:
https://i.imgur.com/9Zb0pyE.png
— это другое дело.
чтобы прочитать весь файл за раз »
gc text.txt -raw
Вы смешали в одно "буфер чтения" и размер выходного файла. »
Я? Где? :)
Лично я говорил о том, что вредно помещать весь файл (при условии, что он достаточно большой) в память, чтобы производить с ним дальнейшие манипуляции. О размерах выходного файла заговорил ты, я ничего об этом не писал.
А как только понадобится напилить файл на куски по несколько ГБ (например, чтобы на DVD записать) - так сразу скрипту и поплохеет. »
Чтобы поменьше теоретизировать, предлагаю провести простой эксперимент:
1. Создай текстовый файл (UTF8, хотя это неважно), в 10000000 строк, с одним символом в каждой строке. Размер у него получится не сильно большим (чуть больше 28Мб), но достаточным для эксперимента. Возможно, конфигурация компьютера будет влиять на результат, но это можно "поправить" увеличением количества строк. :)
2.
a)
gc text.txt -read 5000000|set-content text-out.txt
b)
gc text.txt|set-content text-out.txt
3. Приведи здесь результат эксперимента.
Мои результаты:
a) TotalSeconds : 6,9191207
b) Неадекватное потребление физ.памяти до 3,5Гб и более процессом powershell, нагрузка процессора в 50% и более, плюс подвисания интерфейса windows. Терпения, чтобы дождаться окончания процесса (если это реально), у меня не хватило. В общем, плохеет не только скрипту и размер у файла не очень-то огромный... :)
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.