PDA

Показать полную графическую версию : Разделение текстового файла на части без разделения абзацев


Re:Flex
07-07-2013, 08:19
Здравствуйте, помогите с написанием bat файла, который разбивает большой текстовый файл на части примерно на 500 Кб, но не разбивая абзацы.

То есть скрипт должен отсчитать 500 Кб, потом дойти до двух пустых строк и в этом месте разделить файл.

Iska
07-07-2013, 08:33
Re:Flex, выложите часть файла в виде нескольких абзацев, упакованную в архив.

примерно на 500 Кб »
То есть скрипт должен отсчитать 500 Кб, »
Примерно — это сколько? Вас устроит ближайшее значение до 500 Кб или ближайшее значение свыше 500 Кб? Кстати, почему такая некруглая цифра, почему не 512?

Re:Flex
07-07-2013, 09:00
Эти все вопросы не критичны для меня, поскольку все абзацы маленькие от 1 до 2 Кб, а размер сегментов я потом подправлю после экспериментов.

Re:Flex
07-07-2013, 10:22
PowerShell устроит? »
Спасибо конечно, но нет, у меня он похоже отсутствует в системе :(

Iska
07-07-2013, 19:44
Re:Flex, на WSH, пробуйте:
Option Explicit

Dim lngPartSize
Dim intMaxPartCount

Dim strSourceFile

Dim objRegExp
Dim objMatch

Dim strContent

Dim intPartNumber
Dim lngPos
Dim strPartFileName


If WScript.Arguments.Count = 1 Then
With WScript.CreateObject("Scripting.FileSystemObject")
strSourceFile = .GetAbsolutePathName(WScript.Arguments.Item(0))

lngPartSize = 500 * 2^10 ' 500Kb
intMaxPartCount = 999 ' Не более 999 частей

If .FileExists(strSourceFile) Then
Set objRegExp = WScript.CreateObject("VBScript.RegExp")

With objRegExp
.Global = True

.Pattern = "[\s\S]{" & CStr(lngPartSize) & "}[\s\S]*?\r\n\r\n"
End With

With .OpenTextFile(strSourceFile)
strContent = .ReadAll()
.Close
End With

intPartNumber = 0
lngPos = 0

If objRegExp.Test(strContent) Then
For Each objMatch In objRegExp.Execute(strContent)
intPartNumber = intPartNumber + 1
strPartFileName = .BuildPath(.GetParentFolderName(strSourceFile), .GetBaseName(strSourceFile) & ".part" & Right(String(Len(CStr(intMaxPartCount)), "0") & CStr(intPartNumber), Len(CStr(intMaxPartCount))) & "." & .GetExtensionName(strSourceFile))

With .CreateTextFile(strPartFileName, True)
.Write objMatch.Value
.Close
End With

lngPos = objMatch.FirstIndex + objMatch.Length
WScript.Echo FormatPercent(lngPos / Len(strContent), 1) & ": Write file [" & strPartFileName & "]: " & CStr(objMatch.Length) & " b."
Next
End If

intPartNumber = intPartNumber + 1
strPartFileName = .BuildPath(.GetParentFolderName(strSourceFile), .GetBaseName(strSourceFile) & ".part" & Right(String(Len(CStr(intMaxPartCount)), "0") & CStr(intPartNumber), Len(CStr(intMaxPartCount))) & "." & .GetExtensionName(strSourceFile))

With .CreateTextFile(strPartFileName, True)
.Write Right(strContent, Len(strContent) - lngPos)
.Close
End With

WScript.Echo FormatPercent(1, 1) & ": Write file [" & strPartFileName & "]: " & CStr(Len(strContent) - lngPos) & " b."
Else
WScript.Echo "Source file [" & strSourceFile & "] not found."
End If
End With
Else
WScript.Echo "Usage: cscript.exe //nologo " & WScript.ScriptName & " <Source file>"
End If

WScript.Quit 0


Возможный результат (для некоего случая с «lngPartSize = 30» и файлом «0001.txt»):
8.9%: Write file [E:\Песочница\0289\0001.part001.txt]: 62 b.
18.0%: Write file [E:\Песочница\0289\0001.part002.txt]: 64 b.
25.9%: Write file [E:\Песочница\0289\0001.part003.txt]: 55 b.
33.8%: Write file [E:\Песочница\0289\0001.part004.txt]: 55 b.
41.6%: Write file [E:\Песочница\0289\0001.part005.txt]: 55 b.
53.4%: Write file [E:\Песочница\0289\0001.part006.txt]: 82 b.
65.1%: Write file [E:\Песочница\0289\0001.part007.txt]: 82 b.
76.8%: Write file [E:\Песочница\0289\0001.part008.txt]: 82 b.
88.6%: Write file [E:\Песочница\0289\0001.part009.txt]: 82 b.
100.0%: Write file [E:\Песочница\0289\0001.part010.txt]: 80 b.

Re:Flex
08-07-2013, 14:43
на WSH, пробуйте »
Вот спасибо, всё работает как надо, только системные требования у скрипта безграничные. Он весь файл в память помещает?

Iska
08-07-2013, 18:51
Он весь файл в память помещает? »
Весь:

With .OpenTextFile(strSourceFile)
strContent = .ReadAll()
.Close
End With

А Ваш «большой текстовый файл» какого размера?

Re:Flex
08-07-2013, 21:22
Пока что ~430 Мб максимальный попадался, в будущем может побольше попадаться.

Надеюсь не будет проблемы с "Не более 999 частей" с сегментами по 485 Кб и исходным более 485 Мб.

Iska
09-07-2013, 02:57
Пока что ~430 Мб максимальный попадался, в будущем может побольше попадаться. »
Тогда придётся перебором, наподобие приведённого выше (http://forum.oszone.net/post-2180591.html#post2180591).

Надеюсь не будет проблемы с "Не более 999 частей" с сегментами по 485 Кб и исходным более 485 Мб. »
;): intMaxPartCount = 999999999 ' Не более 999999999 частей
— устроит? Я просто не стал писать код для примерного определения потребного количества частей.

Iska
09-07-2013, 04:35
Тогда придётся перебором »
Ну, вот, примерно так:
Option Explicit

Dim lngPartSize
Dim intMaxPartCount

Dim strSourceFile

Dim objTS

Dim strLine
Dim strContent

Dim intPartNumber
Dim strPartFileName

Dim boolPrevLineIsEmpty
Dim lngTotalWrite


If WScript.Arguments.Count = 1 Then
With WScript.CreateObject("Scripting.FileSystemObject")
strSourceFile = .GetAbsolutePathName(WScript.Arguments.Item(0))

lngPartSize = 500 * 2^10 ' 500Kb

If .FileExists(strSourceFile) Then
intMaxPartCount = .GetFile(strSourceFile).Size \ lngPartSize + 1

strContent = ""
boolPrevLineIsEmpty = False

intPartNumber = 0
lngTotalWrite = 0

Set objTS = .OpenTextFile(strSourceFile)

Do Until objTS.AtEndOfStream
strLine = objTS.ReadLine()
strContent = strContent & strLine & vbCrLf

If Len(strContent) >= lngPartSize Then
If Len(strLine) = 0 Then
If boolPrevLineIsEmpty Then
intPartNumber = intPartNumber + 1
strPartFileName = .BuildPath(.GetParentFolderName(strSourceFile), .GetBaseName(strSourceFile) & ".part" & Right(String(Len(CStr(intMaxPartCount)), "0") & CStr(intPartNumber), Len(CStr(intMaxPartCount))) & "." & .GetExtensionName(strSourceFile))

With .CreateTextFile(strPartFileName, True)
.Write strContent
.Close
End With

lngTotalWrite = lngTotalWrite + Len(strContent)

WScript.Echo FormatPercent(lngTotalWrite / .GetFile(strSourceFile).Size, 1) & ": Write file [" & strPartFileName & "]: " & CStr(Len(strContent)) & " b."

strContent = ""
boolPrevLineIsEmpty = False
Else
boolPrevLineIsEmpty = True
End If
End If
End If
Loop

intPartNumber = intPartNumber + 1
strPartFileName = .BuildPath(.GetParentFolderName(strSourceFile), .GetBaseName(strSourceFile) & ".part" & Right(String(Len(CStr(intMaxPartCount)), "0") & CStr(intPartNumber), Len(CStr(intMaxPartCount))) & "." & .GetExtensionName(strSourceFile))

With .CreateTextFile(strPartFileName, True)
.Write strContent
.Close
End With

lngTotalWrite = lngTotalWrite + Len(strContent)

WScript.Echo FormatPercent(lngTotalWrite / .GetFile(strSourceFile).Size, 1) & ": Write file [" & strPartFileName & "]: " & CStr(Len(strContent)) & " b."

objTS.Close

Set objTS = Nothing
Else
WScript.Echo "Source file [" & strSourceFile & "] not found."
End If
End With
Else
WScript.Echo "Usage: cscript.exe //nologo " & WScript.ScriptName & " <Source file>"
End If

WScript.Quit 0
но чудес производительности от него не ждите.




© OSzone.net 2001-2012