2015-05-21 2 views
0

Есть ли быстрая реализация в Powershell для случайного перетасовки и разбиения текстового файла на 15 миллионов строк с использованием раскола 15% -85%?Powershell random shuffle/split large text file

Многие источники говорят о том, как сделать это с помощью Get-Content, но Get-Content и Get-Random медленно для больших файлов:

Get-Content "largeFile.txt" | Sort-Object{Get-Random}| Out-file "shuffled.txt" 

Я искал решения с использованием потоковых чтения и поток-Writer , но я не уверен, что это возможно. Linux Баш, кажется, делает это очень быстро для моего файла 15million: How can I shuffle the lines of a text file on the Unix command line or in a shell script?

ответ

0

Я пытался использовать чтобы не взорвать мое использование памяти, так как некоторые из этих файлов имеют размер более 300 МБ. Я не мог найти способ полностью избежать памяти, но вместо того, чтобы помещать файл в память, я создаю случайный массив чисел от 0 до Total Lines. Массив указывает, какие строки помещать в файл образца.

Создать поток чтения для данных

$reader = New-Object -TypeName System.IO.StreamReader("data.txt"); 

Создать поток Writer для тестирования населения

$writer_stream = New-Object -TypeName System.IO.FileStream(
    ("test_population.txt"), 
    [System.IO.FileMode]::Create, 
    [System.IO.FileAccess]::Write); 
$writer= New-Object -TypeName System.IO.StreamWriter(
    $writer_stream, 
    [System.Text.Encoding]::ASCII); 

Создать поток Writer для группы управления

$writer_stream_control = New-Object -TypeName System.IO.FileStream(
    ("control.txt"), 
    [System.IO.FileMode]::Create, 
    [System.IO.FileAccess]::Write); 
$writer_control= New-Object -TypeName System.IO.StreamWriter(
    $writer_stream_control, 
    [System.Text.Encoding]::ASCII); 

Определите размер управления и случайным образом выбирать номера между 0 и общим количеством строк в файле.

$line_count = 10000000 
$control_percent = 0.15 
$control_size = [math]::round($control_percent*$line_count) 

Создайте индекс случайных чисел, чтобы определить, какие строки должны идти в файл образца. Удостоверьтесь в том, что в конце проведите через сортировку.

$idx = Get-Random -count $control_size -InputObject(0..($line_count-1))|sort -Unique 

обозначение $ i как номер строки; используйте $ idx [$ j] как строку, которая должна перейти к образцу файла

$i = 0; $j = 0 
while ($reader.Peek() -ge 0) {  
    $line = $reader.ReadLine() #Read Line 
    if ($idx[$j] -eq $i){ 
     $writer_control.WriteLine($OutPut) 
     $j++ 
     } 
    else{$writer.WriteLine($OutPut)} 
    } 
    $i++ 

$reader.Close(); 
$reader.Dispose(); 

$writer.Flush(); 
$writer.Close(); 
$writer.Dispose(); 

$writer_control.Flush(); 
$writer_control.Close(); 
$writer_control.Dispose(); 
1

Не уверен, если это будет достаточно рандомизированное/перемешиваются, но это должно быть быстрее:

$Idxs = 0..999 
Get-Content "largeFile.txt" -ReadCount 1000 | 
foreach { 
$sample = Get-Random -InputObject $Idxs -Count 150 
$_[$sample] | 
Add-Content 'shuffled.txt' 
} 
+0

Я не думаю, что это рандомизированное достаточно. Является ли это перетасовкой каждой группы из 1000 строк между собой? Я также попытался использовать -ReadCount 0, чтобы вытащить весь файл ... но это взорвало мою память. – jgaw