Как разделить текстовый файл с помощью PowerShell? - PullRequest
64 голосов
/ 16 июня 2009

Мне нужно разделить большой (500 МБ) текстовый файл (файл исключений log4net) на управляемые куски, например, 100 5 МБ файлов.

Я думаю, это будет прогулка по парку для PowerShell. Как я могу это сделать?

Ответы [ 14 ]

1 голос
/ 21 сентября 2016

Похоже на задание для команды UNIX:

split MyBigFile.csv

Просто разделите мой csv-файл на 55 ГБ на 21 тыс. Блоков менее чем за 10 минут.

Хотя он не является родным для PowerShell, но поставляется, например, с пакетом git for windows https://git -scm.com / download / win

0 голосов
/ 10 ноября 2017

Вот мое решение разделить файл с именем patch6.txt (около 32 000 строк) на отдельные файлы по 1000 строк в каждом. Это не быстро, но это делает работу.

$infile = "D:\Malcolm\Test\patch6.txt"
$path = "D:\Malcolm\Test\"
$lineCount = 1
$fileCount = 1

foreach ($computername in get-content $infile)
{
    write $computername | out-file -Append $path_$fileCount".txt"
    $lineCount++

    if ($lineCount -eq 1000)
    {
        $fileCount++
        $lineCount = 1
    }
}
0 голосов
/ 23 сентября 2016

Поскольку строки могут быть переменными в журналах, я подумал, что лучше всего использовать количество строк для каждого файла. Следующий фрагмент кода обработал 4-миллионный файл журнала строк менее чем за 19 секунд (18,83 .. секунд), разделив его на 500 000 строк:

$sourceFile = "c:\myfolder\mylargeTextyFile.csv"
$partNumber = 1
$batchSize = 500000
$pathAndFilename = "c:\myfolder\mylargeTextyFile part $partNumber file.csv"

[System.Text.Encoding]$enc = [System.Text.Encoding]::GetEncoding(65001)  # utf8 this one

$fs=New-Object System.IO.FileStream ($sourceFile,"OpenOrCreate", "Read", "ReadWrite",8,"None") 
$streamIn=New-Object System.IO.StreamReader($fs, $enc)
$streamout = new-object System.IO.StreamWriter $pathAndFilename

$line = $streamIn.readline()
$counter = 0
while ($line -ne $null)
{
    $streamout.writeline($line)
    $counter +=1
    if ($counter -eq $batchsize)
    {
        $partNumber+=1
        $counter =0
        $streamOut.close()
        $pathAndFilename = "c:\myfolder\mylargeTextyFile part $partNumber file.csv"
        $streamout = new-object System.IO.StreamWriter $pathAndFilename

    }
    $line = $streamIn.readline()
}
$streamin.close()
$streamout.close()

Это можно легко превратить в файл функции или сценария с параметрами, чтобы сделать его более универсальным. Он использует StreamReader и StreamWriter для достижения своей скорости и небольшого объема памяти

0 голосов
/ 27 октября 2015

Мое требование было немного другим. Я часто работаю с файлами ASCII с разделителями-запятыми и табуляцией, где одна строка - это одна запись данных. И они действительно большие, поэтому мне нужно разделить их на управляемые части (сохранив при этом строку заголовка).

Итак, я вернулся к своему классическому методу VBScript и собрал небольшой скрипт .vbs, который можно запустить на любом компьютере Windows (он автоматически запускается механизмом хоста скрипта WScript.exe в Window).

Преимущество этого метода в том, что он использует текстовые потоки, поэтому базовые данные не загружаются в память (или, по крайней мере, не все сразу). Результатом является то, что он исключительно быстрый и не требует много памяти для запуска. Тестовый файл, который я только что разделил с помощью этого сценария на моем i7, имел размер около 1 ГБ, имел около 12 миллионов строк текста и был разбит на 25 файлов по частям (каждый по 500 тысяч строк в каждом) - обработка заняла около 2 минут и он не превышал 3 МБ памяти, используемой в любой момент.

Предостережение заключается в том, что он опирается на текстовый файл, имеющий «строки» (то есть каждая запись ограничена CRLF), поскольку объект Text Stream использует функцию «ReadLine» для обработки одной строки за раз. Но, эй, если вы работаете с файлами TSV или CSV, это прекрасно.

Option Explicit

Private Const INPUT_TEXT_FILE = "c:\bigtextfile.txt"  
Private Const REPEAT_HEADER_ROW = True                
Private Const LINES_PER_PART = 500000                 

Dim oFileSystem, oInputFile, oOutputFile, iOutputFile, iLineCounter, sHeaderLine, sLine, sFileExt, sStart

sStart = Now()

sFileExt = Right(INPUT_TEXT_FILE,Len(INPUT_TEXT_FILE)-InstrRev(INPUT_TEXT_FILE,".")+1)
iLineCounter = 0
iOutputFile = 1

Set oFileSystem = CreateObject("Scripting.FileSystemObject")
Set oInputFile = oFileSystem.OpenTextFile(INPUT_TEXT_FILE, 1, False)
Set oOutputFile = oFileSystem.OpenTextFile(Replace(INPUT_TEXT_FILE, sFileExt, "_" & iOutputFile & sFileExt), 2, True)

If REPEAT_HEADER_ROW Then
    iLineCounter = 1
    sHeaderLine = oInputFile.ReadLine()
    Call oOutputFile.WriteLine(sHeaderLine)
End If

Do While Not oInputFile.AtEndOfStream
    sLine = oInputFile.ReadLine()
    Call oOutputFile.WriteLine(sLine)
    iLineCounter = iLineCounter + 1
    If iLineCounter Mod LINES_PER_PART = 0 Then
        iOutputFile = iOutputFile + 1
        Call oOutputFile.Close()
        Set oOutputFile = oFileSystem.OpenTextFile(Replace(INPUT_TEXT_FILE, sFileExt, "_" & iOutputFile & sFileExt), 2, True)
        If REPEAT_HEADER_ROW Then
            Call oOutputFile.WriteLine(sHeaderLine)
        End If
    End If
Loop

Call oInputFile.Close()
Call oOutputFile.Close()
Set oFileSystem = Nothing

Call MsgBox("Done" & vbCrLf & "Lines Processed:" & iLineCounter & vbCrLf & "Part Files: " & iOutputFile & vbCrLf & "Start Time: " & sStart & vbCrLf & "Finish Time: " & Now())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...