Erstellen Sie Listen mit einer bestimmten Länge mithilfe mehrerer anderer Listen

458
Werner Schoemaker

Ich habe viele relativ kleine Dateien mit etwa 350.000 Textzeilen. Zum Beispiel:

Datei 1:

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

Datei 2:

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

Wie Sie sehen, ist Zeile 3 von Datei 2 ein Duplikat von Zeile 1 in Datei 1. Ich möchte ein Programm / Notepad ++ Plugin, das diese Duplikate in mehreren Dateien prüfen und entfernen kann.

Das nächste Problem, das ich habe, ist, dass ich möchte, dass alle Listen in 1.000.000 Zeilen großen Dateien zusammengefasst werden. Ich habe zum Beispiel folgende Dateien:

  • 648563 Zeilen
  • 375924 Zeilen
  • 487036 Zeilen

Ich möchte, dass sie diese Dateien ergeben:

  • 1.000.000 Zeilen
  • 511,523 Zeilen

Die letzten beiden Dateien müssen nur aus eindeutigen Zeilen bestehen. Wie kann ich das machen? Kann ich dafür einige Programme verwenden? Oder eine Kombination mehrerer Notepad ++ - Plugins? Ich weiß, dass GSplit Dateien von 1.536.243 in Dateien mit 1.000.000 und 536.243 Zeilen aufteilen kann, aber das reicht nicht aus und entfernt keine Duplikate.

Ich möchte bei Bedarf mein eigenes Notepad ++ - Plugin oder ein eigenes Programm erstellen, weiß jedoch nicht, wie und wo ich anfangen soll.

Danke im Voraus.

0
Sie können dazu Excel verwenden. Kopieren Sie einfach den Text aller Ihrer Textdateien in eine Excel-Spalte und verwenden Sie dann die Option zum Löschen von Duplikaten in Excel. Yacine vor 7 Jahren 0
@Yacine Ich denke, das ist praktisch unmöglich, da im Laufe der Zeit immer mehr Dateien hinzugefügt werden, und ich habe derzeit etwa 10 Millionen Zeilen. Und wenn ich es so machen würde, wie kann ich dann alles in Dateien von 1 Million Zeilen exportieren? Werner Schoemaker vor 7 Jahren 0
Dies erscheint für Befehlszeilen-Dienstprogramme selbstverständlich. In Linux würden Sie folgendes verwenden: `cat" File "* | sortieren | uniq | split -d -l 1000000 - kombiniert.`; Dies würde `Combined.00`,` Combined.01`, generieren. Es gibt Windows-Versionen aller dieser Dienstprogramme, obwohl die Laufzeichenfolgen leicht abweichen können. AFH vor 7 Jahren 1
@AFH Ihre Lösung funktioniert ziemlich gut, mit Ausnahme des 'Split'-Teils. Ich kann kein Windows-Äquivalent dafür finden. Hast du eine Idee, wie ich das lösen könnte? Das Kombinieren, Sortieren, Entfernen von Duplikaten und das Speichern in einer neuen Datei funktioniert sehr gut. Werner Schoemaker vor 7 Jahren 0
Es ist unter anderem in den Dienstprogrammen in [win-bash] enthalten (https://sourceforge.net/projects/win-bash/). AFH vor 7 Jahren 0
nonono :) nicht win-bash. Dies ist 2017. Verwenden Sie PowerShell. Wouter vor 7 Jahren 0

1 Antwort auf die Frage

0
Werner Schoemaker

Ich habe ein Skript für Windows Powershell erstellt und es als .ps1-Datei gespeichert. Ich habe es wie folgt erstellt:

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

Dieser Teil dient nur zum Zurücksetzen aller grundlegenden Variablen. $linecountwird für die Anzahl der Zeilen verwendet, die in den neuen Teilen erstellt werden (sprechen Sie später darüber). $editfilenumberwird für die Dateinummer verwendet, die bearbeitet wird (Duplikate entfernt, Invaliden entfernt ...). $endfilenumberwird für die Teilenummer verwendet, die erstellt wurde. $totallineswird für die Gesamtzahl der Zeilen verwendet. $iwird zur Berechnung der Prozentsätze verwendet. $intervalwird für das Aktualisierungsintervall des Fortschrittsbalkens verwendet (sonst wäre der Prozess sehr langsam)

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

Dies fordert den Benutzer grundsätzlich nach den Daten und nach der Anzahl der Zeilen in den Teilen.

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

Dadurch werden alle TXT-Dateien im angegebenen Verzeichnis aufgelistet. Auf diese Weise wird dem Benutzer mitgeteilt, welche Dateien verwendet werden.

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

Dies wartet auf die Bestätigung des Benutzers, indem auf das Drücken einer Taste gewartet wird.

$start = Get-Date 

Dadurch wird der aktuelle Zeitstempel zum Berechnen der Bearbeitungszeit am Ende abgerufen.

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

Dieser Teil ist sehr wichtig. Zuerst wird angezeigt, welche Datei bearbeitet wird, und $listder Inhalt dieser Datei wird erstellt. Danach wird es alle einzigartigen Linien (und damit das Entfernen von Duplikaten) bekommt, ungültige Zeilen entfernen (müssen für die Zwecke des Programms festgelegt werden) und fügt schließlich das gefilterte $listzu $longlist. Dies erfolgt für jede Datei und somit wird jede gefilterte Datei hinzugefügt $longlist.

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

Dadurch werden alle Duplikate entfernt $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" 

Dadurch wird die Gesamtzahl der eindeutigen gültigen Zeilen berechnet. Dies ist für die Benutzerinformationen und wird verwendet, um den Fortschritt in der Fortschrittsleiste zu berechnen.

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

Dies ist der wichtigste Teil. Es erstellt eine Datei mit dem angegebenen Dateinamen im angegebenen Verzeichnis. Sie fügt dieser Datei eine Zeile $ longlist hinzu. Dann erhöht es sich $linecountund $imit 1. Wenn $linecountdann der angegebenen maximalen Dateigröße entspricht, wird es um $endfilecount1 erhöht . Andernfalls wird die nächste Zeile zur vorhandenen Datei hinzugefügt.

Die angegebene Dateigröße beträgt beispielsweise 10.000 Zeilen und der Teilname lautet Part$endfilenumber. Die erste Zeile von $longlistwird der Datei Part1.txt hinzugefügt ( $endfilenumber = 1wie in der ersten Codezeile angegeben). Wenn die Zeile 10.00 hinzugefügt wird, wird die IfAnweisung verwendet. Das bedeutet, dass die Anzahl $endfilenumberum 1 erhöht wird. Auf diese Weise wird die nächste Zeile $longlistzu einer neuen Datei mit dem Namen Part2.txt (weil $endfilenumber = 2) hinzugefügt .

Die zweite if -Anweisung wird zur Berechnung des Fortschritts verwendet. Das ist nicht sehr wichtig. Um Zeit zu sparen, werde ich das nicht erklären.

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

Dies ist der letzte Teil des Codes. Dies nimmt den Zeitstempel und subtrahiert ihn vom Zeitstempel am Anfang. Auf diese Weise wird die Verarbeitungszeit in Minuten berechnet und auf 2 Dezimalstellen gerundet. Das letzte Bit wartet nur darauf, dass der Benutzer das Programm beendet und beendet.

Ich habe gehofft, das hilft ein bisschen.

HINWEIS: Dieses Programm wirkt sich NICHT auf die Originaldateien aus! Also das ist schön, schätze ich ...

In der Praxis dienen Ihre Antworten nicht nur dazu, Ihnen zu helfen - es ist die nächste Person mit dem gleichen Problem. Wenn Sie Ihr Powershell-Skript veröffentlichen, sollten Sie den [denvercoder / xkcd 979-Effekt] vermeiden (https://xkcd.com/979/). ) Journeyman Geek vor 7 Jahren 0