Ersetzen von mehr als 6000 Zeichenfolgen in einer Textdatei mit mehr als 2 GB

481
HansPeter

Ich möchte mehr als 6000 Zeichenfolgen in einer Textdatei mit mehr als 2 GB suchen und ersetzen.

sed -i "s/search/replace/g" 2gbfile.log 

dauert ewig. Vor allem, wenn Sie es 6000+ Mal tun müssen.

Also habe ich mir ein Skript ausgedacht, das die 2 GB große Datei in Blöcke aufteilt, so dass ich den Aufwand parallelisieren kann. Ich führe 48 Prozesse gleichzeitig aus (64 Kerne verfügbar), aber es dauert immer noch ziemlich lange.

#!/usr/bin/env bash  echo "sorting..." sort bigbigbigfile | awk -F, '' > bigbigbigfile.work  CPUS=$(( $(lscpu |grep "On-line CPU(s) list"|grep -Eo '0-[0-9]+'|cut -f2 -d-) + 1)) CPUSUSABLE=$(echo "$CPUS*0.75" | bc | cut -f1 -d.) NUMLINES=$(cat all-temperatures.sort | wc -l) SPLIT=$(echo "$NUMLINES / $CPUSUSABLE" | bc | cut -f1 -d.) echo "cutting..." split -l $SPLIT bigbigbigfile.work chunkstoworkwith  mapfile -t REPLACEME < replace.list  echo "seding..." for chunk in $(ls chunkstoworkwith*); do ( for i in "${!REPLACEME[@]}"; do counter=$(( counter + 1 )) sed -i "s/ $ / $counter /g" $chunk done ) & done 

Das funktioniert. Aber ich denke, es könnte noch schneller gehen, wenn ich im Arbeitsspeicher suchen und ersetzen möchte, anstatt in-place ersetzen zu müssen und 6000+ in 48 Dateien zu ersetzen. Das summiert sich auf fast 300.000 Sed-Aufrufe, was dazu führt, dass viele Dateien geöffnet / geschlossen / geschrieben werden.

Haben Sie eine Idee, wie Sie dies beschleunigen, die Ersetzung im Speicher durchführen und die Daten nach der Änderung leeren können?

0
HI HansPeter. Willkommen bei SuperUser. Diese Frage scheint bei StackOverflow besser als bei SuperUser zu beantworten, da es sich um ein Bash-Skript handelt. Hast du diese Frage dort gestellt? Stese vor 6 Jahren 0
Stese, nein, habe ich nicht. Wird besorgt. Vielen Dank. HansPeter vor 6 Jahren 0
[Mehrere Such- und Ersetzungsaktionen in einer großen Textdatei] (https://superuser.com/q/618407/241386), [Mehrere Zeichenfolgen in mehreren Dateien ersetzen] (https://stackoverflow.com/q/51608196/995714) ), [Text in sehr großer Datei schnell ersetzen] (https://unix.stackexchange.com/q/255373/44425), [Mehrere Zeichenfolgen in einer großen Textdatei in Python ersetzen] (https://stackoverflow.com/ q / 41192945/995714) phuclv vor 6 Jahren 0

2 Antworten auf die Frage

2
oliv

Ihr Skript analysiert den gesamten Block für jeden einzelnen Ersatz!

Das bedeutet, dass das Skript für jeden Block geöffnet wird, alle Zeilen durchläuft, möglicherweise eine Ersetzung vornimmt, die Datei schließt und die Originaldatei (aufgrund der -iOption) verschiebt.

Vorausgesetzt, Sie möchten das Muster durch eine Zählnummer ersetzen, können Sie alle Ersetzungen gleichzeitig für alle Abschnitte durchführen:

sed -f <(awk '' replace.list) -i "$chunk" 

Die -fOption erlaubt es, ein sed-Skript als Eingabe zu übernehmen und wird für alle Zeilen der $chunkDatei sofort ausgeführt .

Dies wird wahrscheinlich die Gesamtzeit reduzieren ...

Einverstanden. Die erste Verbesserung besteht darin, alle Ersetzungen in einem Dateizugriff durchzuführen. xenoid vor 6 Jahren 0
Großartig, danke! HansPeter vor 6 Jahren 0
0
Xen2050

Ich bin mir nicht ganz sicher, warum Ihr Sed so langsam läuft, Sie müssten wahrscheinlich debuggen oder genauer hinsehen, um wirklich herauszufinden, aber wenn er 6.000-mal schreiben möchte und dadurch langsamer wird, könnten Sie das -ieinfach überspringen hab sed die ganze (geänderte) datei einmal geschrieben:

sed "s/search/replace/g" 2gbfile.log > 2bgfile-AfterSed.log 
Dies würde auch 6000 sed-Aufrufe erfordern (für jedes Muster, das ersetzt werden muss), und es kann nicht parallelisiert werden. HansPeter vor 6 Jahren 0
Sed läuft nur einmal, liest einmal und schreibt einmal, und ich schätze, es könnte das direkte Schreiben sein, das so langsam ist. Wie lange dauert diese Methode? Xen2050 vor 6 Jahren 0
`$ time sed" s / search / replace / g "2gbfile.log> 2bgfile-AfterSed.log #real 0m18.451s" HansPeter vor 6 Jahren 0
(18 * 6000) / 3600 = 30 Stunden. HansPeter vor 6 Jahren 0
Das ist nur 1/6000 der 2 GB-Datei. Wie auch immer, ohne zu wissen, wo der Engpass liegt, raten wir im Allgemeinen nur, Lese- und Schreibvorgänge sind viel langsamer als alle Berechnungen wie ein einfaches Suchen / Ersetzen Xen2050 vor 6 Jahren 0
Das Weiterleiten des Ergebnisses an den nächsten Sed wäre wahrscheinlich schneller als das Speichern des Zwischenergebnisses in einer Datei. Ich denke jedoch, dass dies eine spezielle Lösung erfordert, da es keine allgemeinen Werkzeuge gibt, um eine so große Menge an Zeichenfolgen in einer großen Datei zu ersetzen phuclv vor 6 Jahren 0