Wie kann ich alle Zeilenenden in einer großen Datei (> 100 MB) ersetzen? Ich habe versucht,So ersetzen Sie Zeilenenden in VIM
:%s/\n/, /g
zu tun, aber es ist zu langsam.
Wie kann ich alle Zeilenenden in einer großen Datei (> 100 MB) ersetzen? Ich habe versucht,So ersetzen Sie Zeilenenden in VIM
:%s/\n/, /g
zu tun, aber es ist zu langsam.
Also, ich ging durch und getestet/timed einige der Antworten, die von anderen Menschen gegeben wurden, plus eine Python-Antwort von mir. Hier ist, was ich habe:
tr:
> time tr "\n" "," <lines> line
real 0m1.617s
user 0m0.100s
sys 0m1.520s
Python:
> time python -c 'import sys; print sys.stdin.read().replace("\n",", "),' <lines> line
real 0m1.663s
user 0m0.060s
sys 0m1.610s
awk:
> time awk '{printf("%s, ", $0)}' lines > line
real 0m1.998s
user 0m0.390s
sys 0m1.600s
Perl:
> time perl -e 'while (<>) { chomp; print "$_, " }' lines > line
real 0m2.100s
user 0m0.590s
sys 0m1.510s
sed:
> time sed 's/$/, /g' lines > line
real 0m6.673s
user 0m5.050s
sys 0m1.630s
Hier ist die Datei, die ich verwendet:
> ls -lh lines
-rw-r--r-- 1 some one 101M 2010-03-04 19:54 lines
> wc -l < lines
1300000
> head -n 3 < lines
The pretty pink puma pounced on the unsuspecting aardvark, the scientist watched.
The pretty pink puma pounced on the unsuspecting aardvark, the scientist watched.
The pretty pink puma pounced on the unsuspecting aardvark, the scientist watched.
> head -n 1 < lines | wc -c
82
Ursprünglich war die Timings in Cygwin genommen wurden, haben sie jetzt getroffen worden mit vollständig aktualisiert ubuntu 9.10. Außerdem wurde die Textdateigröße auf 100 MB mit 80 Zeichen breiten Zeilen erhöht. Wie Sie sehen können, ist alles andere als Sed eine gute Idee.
ich bin sehr verdächtig auf Ihre awk Ergebnisse. Zeit, die Sie ein paar Mal befehlen, nicht nur einmal. Python sollte nicht schneller als awk sein, wenn man bedenkt, dass es Zeit braucht, um Module und Sachen zu importieren – ghostdog74
Es wurde ein paar Mal gelaufen, das war durchschnittlich. Ich habe es nur etwa 10 mal, 1.7xx jedes Mal. Vielleicht wäre es anders, wenn ich nicht cygwin awk verwenden würde. –
@ ghostdog74 Sie hatten Recht, meine awk Ergebnisse zu verdächtigen, ich lief es auf einer echten Linux-Box, und es war viel schneller. –
Verwenden Sie dieses Perl-Skript, um durch Ihre Datei zu gehen; es wäre schneller, als alles mit VIM im Speicher zu halten. Passen Sie die Ausgabe einfach an eine neue Datei an.
#!/usr/local/bin/perl
while (<>) {
$_ =~ s/\n/,/g;
print $_;
}
Ich vermute, der Perl-Interpreter ist nicht schlau genug, um zu wissen, dass '$ _' in diesem Fall keine neue Zeile haben kann, außer für das letzte Zeichen -' chomp' ist wahrscheinlich viel schneller. – Cascabel
@Jefromi In meiner völlig unwissenschaftlichen Tests ist es etwa 300 ms schneller, chomp auf eine 100-Megabyte-Datei zu verwenden. –
Müssen Sie dies in vim tun?
Es gibt ein schönes Unix-Dienstprogramm, das zeichenbasierte Übersetzung durchführt. Es heißt tr
. Einige reference.
In Ihrem Fall wäre es:
tr "\n" "," < input_file > output_file
Das ist fast sicher schneller als die Lösungen, die ich gepostet habe, aber leider ersetzt es "," anstelle von "," wie das OP gefordert hat. Ich bin mir nicht sicher, ob es einen Weg gibt, das mit "tr" zu machen, oder? – Cascabel
tr nimmt nur ein Zeichen – ghostdog74
Nein, es ist nicht, ich habe nicht bemerkt, den Platz dort. Um mehr als 1 Zeichen einzugeben, könnte man sed als jemanden verwenden, der unten veröffentlicht wurde. – pajton
:%s/$/, /
von einem :1,$j
gefolgt schneller sein könnte. Ansonsten tut es in einem externen Programm:
perl -e 'while (<>) { chomp; print "$_, " }' input_file > output_file
awk '{printf("%s, ", $0)}' input_file > output_file
Kennen Sie nicht die Spitze von meinem Kopf, die schnellsten sein würde.
'perl -ne 'chomp; Drucken Sie "$ _", "Datei". '-n'" nimmt while-Schleife an " – ghostdog74
Guter Anruf auf dem' -n'. – Cascabel
@sparrkey, "Perl wird schneller ausgeführt" ist nicht gerechtfertigt. – ghostdog74
$ more file
aaaa
bbbb
cccc
dddd
eeee
$ awk 'NR>1{printf("%s, ", p)}{p=$0}END{print p}' file
aaaa, bbbb, cccc, dddd, eeee
$ sed -e :b -e '$!N;s/\n/, /;tb' file
Haben Sie Ihren sed Befehl getestet? sed 'N; s/\ n /, /' Datei – sparkkkey
nicht wirklich. Es ist ein Schnitt eine Paste von Wiki, aber ich denke, Wiki kann manchmal nicht vertraut werden. – ghostdog74
Das beste Werkzeug ist sed und Sie können es verwenden mit:! Befehl
so verwendet :!sed -e 's/\n/,/g' % > %.tmp ; cat %.tmp > % ; rm %.tmp'
Sie benötigen eine tmp-Datei mit Änderung erstellen, bevor in der aktuellen Datei integrieren
hast du deinen sed Befehl getestet? – ghostdog74
ja ich teste es vor – shingara
Warum möchten Sie dies in VIM tun. Sie werden nur mit einer langen Zeile enden, die Sie nicht lesen können (mit Augen, das ist.) Und welche Zeilenenden gibt es auch: DOS, UNIX, MAC oder eine Kombination? – Marichyasana