Powershell 随机 shuffle/split 大文本文件

Powershell random shuffle/split large text file

Powershell 中是否有一个快速实现,可以使用 15%-85% 的拆分随机洗牌和拆分具有 1500 万行的文本文件?

许多消息来源都提到了如何使用 Get-Content 来做到这一点,但是 Get-Content 和 Get-Random 对于大文件来说速度很慢:

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

我一直在寻找使用 Stream-Reader 和 Stream-Writer 的解决方案,但不确定是否可行。 Linux bash 似乎对我的 1500 万文件执行此操作非常快: How can I shuffle the lines of a text file on the Unix command line or in a shell script?

不确定这是否足够randomized/shuffled,但应该更快:

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

我试图使用流 reader/writer 来避免占用内存,因为其中一些文件超过 300MB。我找不到完全避免内存的方法,但我没有将文件放入内存,而是创建了一个介于 0 和总行数之间的随机数字数组。该数组指示将哪些行放入示例文件。

为数据创建流Reader

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

为测试群体创建流编写器

$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_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();