使用多个其他列表创建一定长度的列表

使用多个其他列表创建一定长度的列表

我有很多相对较小的文件,大约有 350,000 行文本。例如:

文件 1:

 1. asdf
 2. wetwert
 3. ddghr
 4. vbnd
 ...
 264187. sdfre

文件 2:

 1. erye
 2. yren
 3. asdf
 4. jkdt
 ...
 184168. uory

如您所见,文件 2 的第 3 行与文件 1 的第 1 行重复。我想要一个程序/ Notepad ++插件来检查并删除多个文件中的这些重复项。

我遇到的下一个问题是,我希望将所有列表合并为 1,000,000 行的大文件。例如,我有以下文件:

  • 648563 行
  • 375924 行
  • 487036 行

我希望它们产生以下文件:

  • 1000000 行
  • 511.523 行

最后两个文件必须仅包含唯一的行。我怎么才能做到这一点?我可以使用一些程序来实现这一点吗?或者多个 Notepad++ 插件的组合?我知道 GSplit 可以将 1.536.243 个文件拆分为 1.000.000 和 536.243 行的文件,但这还不够,而且它不会删除重复项。

如果需要的话,我确实想创建自己的 Notepad++ 插件或程序,但我不知道如何以及从哪里开始。

提前致谢。

答案1

我为 Windows Powershell 编写了一个脚本并将其保存为 .ps1 文件。我将其创建如下:

$linecount = 0 
$editfilenumber = 1
$endfilenumber = 1
$totallines = 0
$i = 0
$interval = 100 / 1

这部分仅用于重置所有基本变量。 $linecount用于新部分中创建的行数(稍后讨论)。用于$editfilenumber正在编辑的文件编号(删除重复项、删除无效项……)。用于$endfilenumber已创建的部分编号。用于$totallines总行数。$i用于计算百分比。$interval用于进度条的刷新间隔(否则过程会非常慢)

$srcdirectory = Read-host "Select path to the source folder"
$partdirectory = Read-host "Select path to where the parts need to be stored"
$maxlines = Read-host "How many lines are in the new parts?"
$maxsize = [int]$maxlines
$partname = Read-host "How do you want the new parts to be called?"

这基本上要求用户提供数据以及各部分的行数。

$files = Get-ChildItem $srcdirectory -filter *.txt
Write-Host "These files will be edited and combined: "
$files | format-table name

这将列出给定目录中的所有 .txt 文件。这样做是为了让用户知道将使用哪些文件。

Write-Host "Press any key to continue..." -foregroundcolor "green"
$HOST.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | OUT-NULL
$HOST.UI.RawUI.Flushinputbuffer()

通过等待按下按键来等待用户确认。

$start = Get-Date

这将获取当前时间戳,以计算最终的处理时间。

ForEach ($file in $files) { 

    Write-host "Editing file: " $file
    Write-host "Loading list..."
    $list = Get-content $srcdirectory\$file
    Write-host "OK" -foregroundcolor "green"

    Write-host "Removing duplicates..."
    $list = $list | Get-Unique
    Write-host "OK" -foregroundcolor "green"

    Write-host "Removing invalid..."
    $list = $list | Where { $_ -notmatch "^@" } | Where { $_ -match "@" }
    $list = $list -replace ';', ':' | Where {$_ -notmatch ':[^\)]+:'} | Where {$_ -notmatch '::'}
    Write-host "OK" -foregroundcolor "green"

    Write-host "Combining lists..."
    $longlist = $longlist + $list | Get-Unique
    $editfilenumber ++
    Write-host "Success!" -foregroundcolor "green"
}

这部分相当重要。首先,它显示正在编辑的文件,并创建$list该文件内容的 。之后,它获取所有唯一行(从而删除重复项),删除无效行(需要为程序的目的而指定),最后将过滤后的 添加到 。$list$longlist每个文件都执行此操作,因此每个过滤后的文件都会添加到$longlist

Write-Host "Removing all duplicates..."
$longlist = $longlist | Get-Unique
Write-Host "Success!" -foregroundcolor "green"

这将从中删除所有重复项$longlist

Write-host "Calculating total number of lines..."
$longlist | % { $totallines += $_.count }
Write-host "There are a total of " $totallines " unique and valid lines." -
foregroundcolor "green"

这将计算唯一有效行的总数。此信息供用户参考,并用于计算进度条中的进度。

Write-host "Creating parts..."
$longlist | ForEach { 
    Add-Content $partdirectory/$partname.$endfilenumber.txt "$_"  
    $linecount++
    $i++
    If ($linecount -eq $maxsize) { 
        Write-host "Success! " $partname$endfilenumber " created" -foregroundcolor "green"
        $endfilenumber++ 
        $linecount = 0 
    } 
    If ($i % $interval -eq 0) {
        $percent = ($i / $totallines) * 100
        $percent = [math]::Round($percent,2)
        Write-Progress -Activity "Creating parts" -Status $percent -PercentComplete $percent
    }
} 

这是最重要的部分。它在指定的目录中创建一个具有指定文件名的文件。它将 1 行 $longlist 添加到该文件。然后它增加$linecount1。$i如果$linecount等于指定的最大文件大小,则它增加$endfilecount1。如果不等于,下一行将添加到现有文件。

例如,指定的文件大小为 10,000 行,部分名称为Part$endfilenumber。 的第一行$longlist添加到文件 Part1.txt($endfilenumber = 1,如代码的第一行中指定)。添加第 10.00 行时,If使用语句。这意味着$endfilenumber增加 1。这样,下一行将从$longlist添加到名为 Part2.txt 的新文件中(因为$endfilenumber = 2)。

第二个 if 语句用于计算进度。这个不是很重要,所以为了节省时间,我就不解释了。

$end = Get-Date
$time = ($end-$start).TotalMinutes
$time = [math]::Round($time,2)

Write-host "A total of " $endfilenumber " parts have been created" -
foregroundcolor "green"
Write-host "Total processing time: " $time " minutes" -foregroundcolor "green"


Write-Host "Press any key to exit..." -foregroundcolor "green"
$HOST.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | OUT-NULL
$HOST.UI.RawUI.Flushinputbuffer()

这是代码的最后一部分。它获取时间戳并将其从开头的时间戳中减去。这样,处理时间以分钟计算,并四舍五入到小数点后 2 位。最后一点只是等待用户确认结束并关闭程序。

我希望这会有点帮助。

注意:此程序不会影响原始文件!所以我觉得这很好...

相关内容