Как разбить большой текстовый файл по повторяющемуся разделителю, а не по номеру строки или точному размеру

У меня около 6000 небольших текстовых файлов. Некоторые имеют только 3 или 4 строки, а некоторые могут иметь 100 или более строк. Я решил объединить их в один большой файл, чтобы их было легче читать. Пакетный файл Windows выполнил слияние, добавив строку «=======» между каждым объединенным файлом, но новый файл имеет размер около 50 МБ и 900 000 строк. Слишком большой. Хотелось бы разделить их на пятьдесят файлов. , около 1 МБ каждый. Программы разделения, которые я рассматривал, либо разбиваются по точному размеру, либо по строкам. Но я не хочу, чтобы конкретный текстовый файл разбивался на две части. заканчиваться "Коричневой лисой", а следующий начинать с Прыжков. Другими словами, рассматривайте все, что находится между разделителем =======, как неразрывную единицу.

Это файл Windows/DOS, поэтому нет необходимости изменять окончания строк CRLF. Этот файл не имеет какой-либо специальной кодировки для печати, раскрашивания и т.д.

Пример объединенного файла:

=======  
One  
Two  
=======  
Abc  
=======  
The quick  
Brown Fox  
Jumps  
Over the dog  
=======  
Dfdfasdf  
Eeffee  
  
Eewweew  
Lk klkl Y tyyd  
=======  


I typed this string on a Windows command line to create the 50MB file All.asc

    For %A in (D:\@temp\*.txt) Do @(CAT53 -s %A & Echo =======) >>D:\@temp\All.asc

When I ran this command, (specifying 30 bytes)
split -b30  all.asc BB
The output for the second file (BBab) elooked like this:
==  
Abc  
=======  
The qu

Я не думал проверять размер файла all.asc после каждой конкатенации и прерывание, если размер превышает 1 МБ, было бы очень эффективным. Я думал, что решение, включающее слияние, а затем разделение, будет проще и можно было бы использовать повторно.

У меня есть утилиты unix на моем ПК, но я не уверен, что sed, awk или split будут полезный. Утилита GSplit, кажется, не делает то, что мне нужно.

Пожалуйста, просмотрите как отформатировать, а затем переформатируйте свой вопрос

markp-fuso 21.02.2023 22:19

Пожалуйста, обновите вопрос с помощью «разделенного» кода, который вы пробовали до сих пор, и объясните, как он потерпел неудачу и/или не сделал то, что вы хотите

markp-fuso 21.02.2023 22:19

Содержит ли файл какие-либо непечатаемые символы (например, цветовые коды, escape-коды, управляющие символы)? содержит ли файл какие-либо многобайтовые символы?

markp-fuso 21.02.2023 22:21

Потенциальные респонденты, не должно быть причин просто публиковать командную строку sed или awk точно так же, как она используется в Unix, без подтверждения того, что это правильный формат и синтаксис для указанной ОС Windows и, при необходимости, сторонних файлов Unix Utilities.

Compo 22.02.2023 01:04

Если вашей главной задачей является обеспечение того, чтобы исходные строки файла не прерывались при разделении объединенного файла, и ни количество строк, ни размер байта не являются критическими, почему бы просто не обработать объединенный файл в awk, установив разделитель записей в =======, и определите, сколько записей нужно напечатать в файлы частей путем оценки и уточнения, начиная, скажем, со 120 записей на разбиение (120 — это 1/50 от 600).

Dave Pritlove 22.02.2023 02:23

Я думаю, что вы приняли неправильное решение об использовании пакетного файла вместо Powershell. Та же задача была решена PS.

Daemon-5 22.02.2023 06:31

Вместо того, чтобы создавать большой файл, а затем разбивать его на более мелкие файлы, почему бы просто не создать файлы меньшего размера в первую очередь, считывая исходные очень маленькие входные файлы, запуская новый выходной файл каждый раз, когда общая длина входных данных достигает 1M символы или подобные?

Ed Morton 22.02.2023 17:50

Я задавался вопросом о времени/накладных расходах на создание файлов меньшего размера в первую очередь вместо того, чтобы потом нарезать файлы. Я мог бы сделать что-то вроде FOR /F "usebackq" %%A IN ('%file%') DO set size=%%~zA после копирования каждого файла, а затем продолжить копирование, если размер был меньше 1 МБ. Я также думал о создании группы папок и перемещении файлов размером 1 МБ в каждую папку.

user2574126 22.02.2023 21:25

@ Daemon-5: Все решения PS, размещенные по вашей ссылке, не соответствуют требованию OP о сохранении блоков строк, разделенных ========. Кроме того, я почти уверен, что полное решение PS будет медленнее, чем эквивалентное пакетное решение при обработке большого файла...

Aacini 23.02.2023 04:39

@user2574126: Да, это тот же метод, который я использовал в моем решении...

Aacini 23.02.2023 04:52
Ускорьте разработку веб-приложений Laravel с помощью этих бесплатных стартовых наборов
Ускорьте разработку веб-приложений Laravel с помощью этих бесплатных стартовых наборов
Laravel - это мощный PHP-фреймворк, используемый для создания масштабируемых и надежных веб-приложений. Одним из преимуществ Laravel является его...
Что такое двойные вопросительные знаки (??) в JavaScript?
Что такое двойные вопросительные знаки (??) в JavaScript?
Как безопасно обрабатывать неопределенные и нулевые значения в коде с помощью Nullish Coalescing
Создание ресурсов API Laravel: Советы по производительности и масштабируемости
Создание ресурсов API Laravel: Советы по производительности и масштабируемости
Создание API-ресурса Laravel может быть непростой задачей. Она требует глубокого понимания возможностей Laravel и лучших практик, чтобы обеспечить...
Как сделать компонент справочного центра с помощью TailwindCSS
Как сделать компонент справочного центра с помощью TailwindCSS
Справочный центр - это веб-сайт, где клиенты могут найти ответы на свои вопросы и решения своих проблем. Созданный для решения многих распространенных...
Асинхронная передача данных с помощью sendBeacon в JavaScript
Асинхронная передача данных с помощью sendBeacon в JavaScript
В современных веб-приложениях отправка данных из JavaScript на стороне клиента на сервер является распространенной задачей. Одним из популярных...
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.
1
10
93
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это может сработать для вас (параллель GNU):

cat file | parallel --pipe --recstart '=======' cat \>part{#}

Направьте файл в параллель.

Размер блока по умолчанию составляет 1M, а --recstart гарантирует, что файл будет разделен на =======.

Выходные файлы называются от part1 до part50.


Файл BTW может быть создан:

sed -s '1i\=======' *.txt >file
Ответ принят как подходящий

Этот пакетный файл делает именно то, что вы хотите. Просто установите желаемый размер выходных файлов в переменной partSize.

@echo off
setlocal EnableDelayedExpansion

set /A partSize=30, part=101, last=0

del part*.txt 2> NUL
echo Creating part # %part:~1%
< all.asc (
for /F "delims=:" %%n in ('findstr /N /B "====== = " all.asc') do (
   set /A "lines=%%n-last, last=%%n"
   (for /L %%i in (1,1,!lines!) do (
      set "line = "
      set /P "line = "
      echo(!line!
   )) >> part!part:~1!.txt
   for %%f in (part!part:~1!.txt) do (
      if %%~Zf gtr %partSize% (
         set /A part+=1
         echo Creating part # !part:~1!
      )
   )
))

Не могли бы вы получить и сообщить время, необходимое этой программе для обработки вашего файла размером 50 МБ?

Aacini 23.02.2023 04:47

Другие вопросы по теме