Grundlegender Befehl sed für große einzeilige Datei: Speicher konnte nicht neu zugeordnet werden

10

Ich habe eine 250 MB Textdatei, alles in einer Zeile.

In dieser Datei möchte ich aZeichen durch bZeichen ersetzen :

sed -e "s/a/b/g" < one-line-250-mb.txt

Es schlägt fehl mit:

sed: couldn't re-allocate memory

Es scheint mir, dass diese Art von Aufgabe inline ausgeführt werden könnte, ohne viel Speicher zuzuweisen.
Gibt es ein besseres Werkzeug für den Job oder eine bessere Verwendung sed?


GNU sed Version 4.2.1
Ubuntu 12.04.2 LTS
1 GB RAM

Nicolas Raoul
quelle
4
Bei dieser Frage handelt es sich um einen sehr komplexen mehrzeiligen Ausdruck. Meine Frage bezieht sich auf den grundlegendsten Ausdruck, den Sie sich vorstellen können.
Nicolas Raoul
@RubanSavvy plus, keine der Antworten auf dem anderen Q berücksichtigt die lange Schlange und tatsächlich hätten beide wahrscheinlich das gleiche Problem.
Terdon
Können Sie Ihre sed-Version in dieses Q aufnehmen und auch Ihre Hardware-Informationen (RAM speziell) und die Distribution-Version?
slm

Antworten:

10

Ja, verwenden Sie trstattdessen:

tr 'a' 'b' < file.txt > output.txt

sedGeschäfte in Linien, so dass eine große Linie es Probleme verursachen wird. Ich gehe davon aus, dass eine Variable intern deklariert wird, um die Zeile zu halten, und Ihre Eingabe die dieser Variablen zugewiesene maximale Größe überschreitet.

tr Auf der anderen Seite handelt es sich um Zeichen und sollte in der Lage sein, beliebig lange Zeilen korrekt zu behandeln.

terdon
quelle
Seltsamerweise habe ich gerade eine 250-MB-Datei mit "abcabc ..." erstellt und konnte sed -e "s/a/z/g" b.txt > c.txtohne Probleme auskommen . Verwendung von sed (GNU sed) 4.2.2.
slm
@slm hier bei einer 496M-Datei und derselben sedVersion gleich, denke, es hängt von der Implementierung oder der Hardware ab.
Terdon
Ja, wenn ich eine Vermutung anstellen müsste, haben wir es mit einer älteren Version von zu tun sed.
slm
5

Historische Versionen von sed und awk hatten Speicherprobleme, diese wurden größtenteils in neueren Versionen behoben, aber eines der klassischen Vorkommen dieses Problems traf Larry Wall ziemlich hart. Seine Antwort war, eine neue Programmiersprache zu schreiben - ohne andere Speicherbeschränkungen als Hardware. Er nannte es Perl. Ihr spezifisches Problem kann einfacher gelöst werden, aber die allgemeine Faustregel, die ich verwende, lautet, wenn sed kein Perl verwendet.

Bearbeiten: auf Anfrage ein Beispiel:

perl -pe "s/a/b/g" < one-line-250-mb.txt

oder für weniger Speicherbedarf:

perl -e 'BEGIN{$/=\32768}' -pe "s/a/b/g" < one-line-250-mb.txt
hildred
quelle
1
Dieser ganze Absatz läuft auf "Perl" hinaus. Einige Details wären nett, oder zumindest ein Beispiel oder so etwas
Michael Mrozek
@MichaelMrozek Mir ist klar, dass die Hutkollektion tendenziell zu Roboediting führt, aber ich dachte mir, dass Sie mit Ihrem Ruf etwas mehr Aufmerksamkeit schenken würden. Insbesondere insofern, als das spezifische Problem bereits auf sehr enge Weise gelöst worden war, was der Mehrheit der Suchenden nicht helfen würde, fügte ich eine Antwort für den allgemeinen Fall hinzu. Die erweiterte Antwort, die ich gegeben habe, hätte Nicolas Raoul geholfen, wenn es nicht bereits eine praktikable Lösung gegeben hätte, aber ich bezweifle, dass sie sehr vielen anderen helfen würde, während meine ursprüngliche Antwort allen helfen würde, die an die Grenzen von sed stießen. Wenn Sie nicht einverstanden sind, werde ich löschen
hildred
@hildred Ich denke nicht, dass es zu viel verlangt, dass Sie die Moderatoren in gutem Glauben annehmen, wenn sie gültige Kommentare zu Ihrer Antwort abgeben, ohne sofort auf Vorwürfe von Hintergedanken zurückzugreifen (Hüte, wirklich?!).
Chris Down
@ ChrisDown Im Gegenteil - ich bin ganz für die Hüte dabei. Auch dies wurde von mehreren Personen nicht als Antwort gekennzeichnet, aber das ist eine entfernte zweite Priorität für die Hüte
Michael Mrozek
Der zweite mit der Speicherbeschränkung hat den Trick gemacht (für meine 2,5-GB-1-Zeilen-Datei): Danke! Etwas enttäuscht von sed. : \
Tomislav Nakic-Alfirevic