Что нового

Разделение текстового файла на маленкие (по 500 строк)

Dk

Новичок
Сообщения
358
Репутация
2
Версия AutoIt: 3.1

Описание:
Здравствуйте
Есть текстовой файл, который содержит примерно 400 тыс строк.
Нужно, что-бы он был разбит на файлы по 500 строк (1.тхт , 2.тх, 3.тхт).

Примечания:
Обязательно что-бы название файлов было 1,2,3,4 итд.

Спасибо.
 

InnI

AutoIT Гуру
Сообщения
4,951
Репутация
1,446
Код:
#include <File.au3>

Global $Path = @ScriptDir & "\all.txt"
Global $Limit = 500

$File = FileOpen($Path)
If $File = -1 Then
  MsgBox(4096, "Ошибка", "Невозможно открыть файл.")
  Exit
EndIf

Global $LinesCount = _FileCountLines($Path), $Lines[$Limit], $Name = 0
If $LinesCount <= $Limit Then Exit

While 1
  For $i = 0 To $Limit - 1
    $Lines[$i] = FileReadLine($File)
    If @error = -1 Then ExitLoop 2
  Next
  $Name += 1
  _FileWriteFromArray(@ScriptDir & "\" & $Name & ".txt", $Lines)
WEnd
If $i > 0 Then
  ReDim $Lines[$i]
  _FileWriteFromArray(@ScriptDir & "\" & $Name + 1 & ".txt", $Lines)
EndIf

FileClose($File)
 
Автор
D

Dk

Новичок
Сообщения
358
Репутация
2
Работает!
Спасибо :laugh:
 

InnI

AutoIT Гуру
Сообщения
4,951
Репутация
1,446
Поправил концовку - теперь не вылетает, если количество строк кратно $Limit.
 

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
тема, конечно , решена. но можно и такой вариант
в $limit вставляем нужное количество строк. в последнем файле будет дописан остаток
Код:
$i = 1
$w = 1
$r = 1
$limit = 6
$fo = FileOpen('q.txt')
While 1
	$frl = FileReadLine($fo, $i)
	If @error Then ExitLoop
	FileWriteLine($r & '.txt', $frl)
	If $w = $limit Then
		$w = 0
		$r += 1
	EndIf
	$w += 1
	$i += 1
WEnd
FileClose($fo)
 
Автор
D

Dk

Новичок
Сообщения
358
Репутация
2
Спасибо, скопирую и этот скрипт себе на заметку :smile:
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Dk,
До кучи и мой вариант. :smile:
Код:
FileDelete(@ScriptDir & '\*.txt')

Global $sTxt, $hFile, $sFile = 'Very_Big_File.txt', $iLimit = 500, $hTmpFile, $iCount, $iRand = Random(400000, 500000, 1)

FileChangeDir(@ScriptDir)
;~ создаем рандомный большой файл Very_Big_File.txt c кол-вом строк $iRand
ConsoleWrite('$iRand: ' & $iRand & @LF)
For $i = 1 To $iRand
    $sTxt &= 'Test string number ' & $i & @CRLF
Next
$hFile = FileOpen($sFile, 2)
FileWrite($hFile, StringTrimRight($sTxt, 2))
FileClose($hFile)
$hFile = 0
$sTxt = ''

;~ делим файл Very_Big_File.txt на файлы 1.txt - n.txt по кол-ву строк $iLimit
Local $iTime = TimerInit()
$hFile = FileOpen($sFile)
While 1
    $sTxt = ''
    For $i = 1 To $iLimit
        $sTxt &= FileReadLine($hFile) & @CRLF
        If @error Then ExitLoop
	Next
	$sTxt = StringRegExpReplace($sTxt, '[\r\n]*$', '')
    If $sTxt Then
        $iCount += 1
        $hTmpFile = FileOpen($iCount & '.txt', 2)
        FileWrite($hTmpFile, $sTxt)
        FileClose($hTmpFile)
    Else
        ExitLoop
    EndIf
WEnd
FileClose($hFile)
ConsoleWrite(StringFormat('Создано файлов: %d. Затрачено %.2f секунд\n', $iCount, TimerDiff($iTime) / 1000))
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
InnI,
Поправил. :-[
 
Автор
D

Dk

Новичок
Сообщения
358
Репутация
2
madmasles До кучи и мой вариант


Ого, у вас вообще мудрённый Вариант :shok:
Спасибо )))
 

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
Можно я, можно я!!! :D
Код:
$aFiles = StringRegExp(FileRead("Src.txt"), '(?>[^\r\n]+(?:[\r\n]+)){0,499}(?>[^\r\n]+)', 3)
For $i = 0 To UBound($aFiles)-1
	$file = FileOpen($i+1 & '.txt', 2)
	FileWrite($file, $aFiles[$i])
	FileClose($file)
Next
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Я тоже хотел сказать, зачем читать файл построчно? Можно ведь считать весь файл целиком, а затем поделить данные на блоки.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Yashied [?]
зачем читать файл построчно? Можно ведь считать весь файл целиком, а затем поделить данные на блоки.
Я так и сделал сначала, а потом решил в ущерб скорости поберечь память, если исходный файл очень большой. А делать по условию, в зависимости от размера, уже лень. :smile:
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
InnI
Функция _FileCountLines уже читает целиком файл, отправляя его в StringSplit.

Я конечно не буду настаивать, но такой вариант слишком медленный для больших файлов.
Набросал вариант, должен работать быстрее:

Код:
Local $sRead = FileRead( "sample.txt" ), $aRead = StringSplit( StringStripCR( $sRead ), @LF ), $iLinesCount = 500
; ---

$FileIdx = 1
While 1
	$iTmpLine = $FileIdx * $iLinesCount
	$iStartLine = $iTmpLine - $iLinesCount
	If $iTmpLine > $aRead[0] Then
		$iEndLine = $aRead[0]
		If $iStartLine > $aRead[0] Then ExitLoop
	Else
		$iEndLine = $iTmpLine
	EndIf

	$sWrite = ''
	For $LineIdx = $iStartLine To $iEndLine Step 1
		$sWrite &= $aRead[$LineIdx] & @CRLF
	Next
	FileWrite( $FileIdx & '.txt', StringTrimRight( $sWrite, 2 ) )

	$FileIdx += 1
WEnd

MsgBox( 64, "End", "Total files: " & $FileIdx - 1 )
 
Верх