Faça listas de determinado tamanho usando várias outras listas

0

Eu tenho muitos arquivos relativamente pequenos com cerca de 350.000 linhas de texto. Por exemplo:

Arquivo 1:

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

Arquivo 2:

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

Como você pode ver, a linha 3 do arquivo 2 é uma duplicata da linha 1 do arquivo 1. Eu quero um programa / Notepad + + Plugin que pode verificar e remover essas duplicatas em vários arquivos.

O próximo problema que tenho é que quero que todas as listas sejam combinadas em grandes 1.000.000 de arquivos de linha. Então, por exemplo, eu tenho esses arquivos:

  • 648563 linhas
  • 375924 linhas
  • 487036 linhas

Eu quero que eles resultem nesses arquivos:

  • 1.000.000 linhas
  • 511,523 linhas

E os últimos 2 arquivos devem consistir em apenas linhas exclusivas. Como eu posso fazer isso? Posso usar alguns programas para isso? Ou uma combinação de múltiplos Plugins do Notepad ++? Eu sei que o GSplit pode dividir arquivos de 1.536.243 em arquivos de 1.000.000 e 536.243 linhas, mas isso não é suficiente, e não remove duplicatas.

Eu quero criar meu próprio plug-in ou programa do Notepad ++, se necessário, mas não tenho ideia de como e onde começar.

Obrigado antecipadamente.

    
por Werner Schoemaker 26.04.2017 / 12:19

1 resposta

0

Eu criei um script para o Windows Powershell e o salvei como um arquivo .ps1. Eu criei da seguinte forma:

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

Esta parte é apenas para redefinir todas as variáveis básicas. $linecount é usado para o número de linhas criadas nas novas partes (fale sobre isso depois). $editfilenumber é usado para o número do arquivo que está sendo editado (Duplicatas removidas, inválidos removidos ...). $endfilenumber é usado para o número da peça que foi criado. $totallines é usado para o número total de linhas. $i é usado para calcular as porcentagens. $interval é usado para o intervalo de atualização da barra de progresso (caso contrário, o processo seria muito lento)

$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?"

Isso basicamente solicita ao usuário os dados e o número de linhas nas partes.

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

Isso listará todos os arquivos .txt no diretório fornecido. Isso é feito para informar ao usuário quais arquivos serão usados.

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

Isso aguarda a confirmação do usuário, esperando que uma tecla seja pressionada.

$start = Get-Date

Isso obtém o timestamp atual para calcular o tempo de processamento no final.

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"
}

Esta parte é muito importante. Primeiro, exibe o arquivo que está sendo editado e cria um $list do conteúdo desse arquivo. Depois disso, ele obtém todas as linhas exclusivas (e, portanto, remove as duplicatas), remove linhas inválidas (precisam ser especificadas para o propósito do programa) e finalmente adiciona o $list a $longlist filtrado. Isso é feito para cada arquivo e, assim, cada arquivo filtrado é adicionado a $longlist .

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

Isso remove todas as duplicatas de $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"

Calcula o número total de linhas válidas exclusivas. Isso é para as informações do usuário e usado para calcular o progresso na barra de progresso.

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
    }
} 

Esta é a parte mais importante. Cria um arquivo com o nome do arquivo especificado no diretório especificado. Adiciona 1 linha de $ longlist a esse arquivo. Em seguida, ele aumenta $linecount e $i com 1. Se $linecount for igual ao tamanho máximo de arquivo especificado, ele aumentará $endfilecount por 1. Se não, a próxima linha será adicionada ao arquivo existente.

Por exemplo, o tamanho especificado do arquivo é de 10.000 linhas e o nome da parte é Part$endfilenumber . A primeira linha de $longlist é adicionada ao arquivo Part1.txt ( $endfilenumber = 1 , conforme especificado nas primeiras linhas de código). Quando a linha 10.00 é adicionada, a instrução If é usada. Isso significa que $endfilenumber é aumentado em 1. Dessa forma, a próxima linha de $longlist será adicionada a um novo arquivo chamado Part2.txt (porque $endfilenumber = 2 ).

A segunda instrução if é usada para calcular o progresso. Isso não é muito importante, então, para economizar tempo, não vou explicar isso.

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

Esta é a última parte do código. Isso recebe o registro de data e hora e o subtrai do registro de data e hora no início. Desta forma, o tempo de processamento é calculado em minutos e arredondado para 2 decimais. O último bit apenas aguarda a confirmação do usuário para finalizar e fechar o programa.

Espero que isso ajude um pouco.

NOTA: Este programa NÃO afeta os arquivos originais! Então é legal, eu acho ...

    
por 28.04.2017 / 11:20