Ersetzen von Zeichenfolgen in einer sehr großen Datei

Ersetzen von Zeichenfolgen in einer sehr großen Datei

Ich habe eine sehr lange Reihe von URLs ohne Trennzeichen im gleichen Format wie unten:

http://example.comhttp://example.nethttp://example.orghttp://etc...

Ich möchte, dass jede URL in einer neuen Zeile steht. Ich habe versucht, dies zu erreichen, indem ich alle Vorkommen von "http://" durch "\nhttp://" ersetzt habe. Dazu habe ich sed verwendet.

sed 's_http://_\nhttp://_g' urls.txt

aber es tritt ein Segmentierungsfehler auf (Speicherverletzung). Ich kann nur vermuten, dass die schiere Größe der Datei (über 100 GB) dazu führt, dass sed ein bestimmtes Limit überschreitet.

Ich könnte die Datei zur Verarbeitung in mehrere kleinere Dateien aufteilen, aber alle Vorkommen von „http://“ müssten erhalten bleiben.

Gibt es eine bessere Möglichkeit, dies zu tun?

Antwort1

Mit awkkönnen Sie das Lesen riesiger Textmengen auf einmal vermeiden:

awk -vRS='http://' -vORS='\nhttp://' 1 urls.txt > urlsperline.txt

Der Erfolg kann von der verwendeten Implementierung abhängen . Funktioniert awkbeispielsweise einwandfrei, stürzt aber ab.gawkmawk

Antwort2

Das hier wird es richten:

perl -pe 'BEGIN { $/ = "//" } s!(?=http://\z)!\n!' urls.txt

Indem man es einstellt$/, ich habe die Definition einer Zeile geändert, sodass sie mit //statt mit einem Zeilenumbruch endet. Dadurch liest Perl jeweils eine URL. Es ist unwahrscheinlich, dass eine URL //nach dem Schema „except“ enthält, aber es ist OK, wenn doch, denn der reguläre Ausdruck verhindert, dass falsche Zeilenumbrüche hinzugefügt werden.

Wenn Sie das Einfügen einer Leerzeile vor der ersten URL vermeiden möchten:

perl -pe 'BEGIN { $/ = "//"; print scalar <> } s!(?=http://\z)!\n!' urls.txt

Sie können einen Benchmarking-Test durchführen, um zu sehen, ob s!http://\z!\nhttp://!es schneller ist. Sie sind gleichwertig. Beachten Sie, dass das /gFlag bei der Ersetzung nicht erforderlich ist, da es nur eine Übereinstimmung pro „Zeile“ geben kann.

Antwort3

  1. Ersetzen Sie alle Vorkommen von :durch einen Zeilenumbruch, um die Datei zu zerstückeln.
  2. Ersetzen
    • httpam Ende der Zeile mit
    • eine neue Zeile gefolgt von http:und fügen Sie die nächste Zeile daran an
  3. Einmal wiederholen, damit gerade und ungerade Zeilen aktualisiert werden

Diese Schritte sehen wie folgt aus:

tr ':' '\n' | sed -e '/http$/{N;s/http\n/\nhttp:/}' | sed -e '/http$/{N;s/http\n/\nhttp:/}'
  1. Überprüfen Sie, ob es Zeilen gibt, die nicht mit beginnen http://, und drucken Sie die Zeilennummern. Dies würde nur auftreten, wenn ein : an einer anderen Stelle in der URL als nach dem steht http.

    grep -nv '^http://'

verwandte Informationen