
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 awk
kö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 awk
beispielsweise einwandfrei, stürzt aber ab.gawk
mawk
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 /g
Flag bei der Ersetzung nicht erforderlich ist, da es nur eine Übereinstimmung pro „Zeile“ geben kann.
Antwort3
- Ersetzen Sie alle Vorkommen von
:
durch einen Zeilenumbruch, um die Datei zu zerstückeln. - Ersetzen
http
am Ende der Zeile mit- eine neue Zeile gefolgt von
http:
und fügen Sie die nächste Zeile daran an
- 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:/}'
Ü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 stehthttp
.grep -nv '^http://'