In dieser Antwort ( Wie kann ich die erste Zeile einer Datei mit sed entfernen? ) Gibt es zwei Möglichkeiten, den ersten Datensatz in einer Datei zu löschen:
sed '1d' $file >> headerless.txt
** ---------------- ODER ----------------**
tail -n +2 $file >> headerless.txt
Persönlich denke ich, dass die tail
Option kosmetisch ansprechender und lesbarer ist, aber wahrscheinlich, weil ich herausgefordert bin.
Welche Methode ist am schnellsten?
sed
es portabler ist: "+2" fürtail
funktioniert gut unter Ubuntu, das GNU verwendettail
, aber unter BSD nicht funktionierttail
.tail
fehlende plattformübergreifende Kompatibilität.-n
Option nicht bereitgestellt und die Syntax verwendettail +2 $file
. Siehe freebsd.org/cgi/… Möglicherweise haben Sie eher daran gedacht als an eines der modernen BSDs.Antworten:
Leistung von
sed
vs.tail
, um die erste Zeile einer Datei zu entfernenTL; DR
sed
ist sehr leistungsfähig und vielseitig, aber das macht es langsam, besonders für große Dateien mit vielen Zeilen.tail
macht nur eine einfache Sache, aber diese macht es gut und schnell, auch für größere Dateien mit vielen Zeilen.Für kleine und mittlere Dateien
sed
undtail
mit ähnlich hoher Geschwindigkeit (oder geringer Geschwindigkeit, je nach Ihren Erwartungen). Bei größeren Eingabedateien (mehrere MB) nimmt der Leistungsunterschied jedoch erheblich zu (eine Größenordnung für Dateien im Bereich von Hunderten von MB), wobei einetail
deutliche Outperformance erzielt wirdsed
.Experiment
Allgemeine Vorbereitungen:
Unsere zu analysierenden Befehle sind:
Beachten Sie, dass ich die Ausgabe
/dev/null
jedes Mal weiterleite, um die Terminalausgabe oder die Dateischreibvorgänge als Leistungsengpass zu beseitigen.Richten wir eine RAM-Disk ein, um die Festplatten-E / A als potenziellen Engpass zu beseitigen. Ich persönlich habe ein
tmpfs
Reittier bei,/tmp
also habe ich es einfachtestfile
für dieses Experiment hingestellt.Dann erstelle ich
$numoflines
mit diesem Befehl einmal eine zufällige Testdatei mit einer festgelegten Anzahl von Zeilen mit zufälliger Zeilenlänge und zufälligen Daten (beachten Sie, dass dies definitiv nicht optimal ist, da es für über 2 Millionen Zeilen sehr langsam wird, aber wen interessiert das, es ist nicht das was wir analysieren):Oh, übrigens. Auf meinem Test-Laptop läuft Ubuntu 16.04, 64-Bit auf einer Intel i5-6200U-CPU. Nur zum Vergleich.
Timing großer Dateien:
Riesen aufbauen
testfile
:Wenn Sie den obigen Befehl mit
numoflines=10000000
einer zufälligen Datei ausführen, die 10 Millionen Zeilen enthält und etwas mehr als 600 MB belegt - das ist ziemlich umfangreich, aber fangen wir damit an, denn wir können:Führen Sie den zeitgesteuerten Lauf mit unserem riesigen
testfile
:Lassen Sie uns nun zunächst mit beiden Befehlen einen einzigen zeitgesteuerten Lauf durchführen, um abzuschätzen, mit welchen Größen wir arbeiten.
Wir sehen bereits ein wirklich eindeutiges Ergebnis für große Dateien, das
tail
um eine Größenordnung schneller ist alssed
. Aber nur zum Spaß und um sicherzugehen, dass es keine zufälligen Nebenwirkungen gibt, die einen großen Unterschied machen, machen wir es 100 Mal:Die Schlussfolgerung bleibt gleich,
sed
ist ineffizient, um die erste Zeile einer großen Datei zu entfernen,tail
sollte dort verwendet werden.Und ja, ich weiß, dass die Loop-Konstrukte von Bash langsam sind, aber wir machen hier nur relativ wenige Iterationen, und die Zeit, die eine einfache Loop benötigt, ist im Vergleich zu den
sed
/tail
-Laufzeiten sowieso nicht signifikant .Timing kleiner Dateien:
Ein kleines einrichten
testfile
:Betrachten wir der Vollständigkeit halber den häufigeren Fall, dass Sie eine kleine Eingabedatei im kB-Bereich haben. Lass uns eine zufällige Eingabedatei erstellen
numoflines=100
, die so aussieht:Führen Sie den zeitgesteuerten Lauf mit unserem kleinen
testfile
:Da wir aus Erfahrung damit rechnen können, dass das Timing für solche kleinen Dateien im Bereich einiger Millisekunden liegt, lassen Sie uns gleich 1000 Iterationen durchführen:
Wie Sie sehen, sind die Timings ziemlich ähnlich, es gibt nicht viel zu interpretieren oder sich darüber zu wundern. Für kleine Dateien sind beide Tools gleich gut geeignet.
quelle
awk
dies auch kann. Meine ursprüngliche Frage basierte auf dem Link, den ich an erster Stelle gefunden hatte. Bitte geben Sie nach all Ihrer harten Arbeit an, ob ichawk
als Lösungskandidat entfernen und den Fokus wieder auf den ursprünglichen Projektumfang von nursed
und legen solltail
.awk 'NR > 1'
interessanterweise).Hier ist eine weitere Alternative, bei der nur Bash-Builtins verwendet werden
cat
:$file
wird in die{ }
Befehlsgruppierung umgeleitet . Derread
liest und verwirft einfach die erste Zeile. Der Rest des Streams wird dann weitergeleitetcat
und in die Zieldatei geschrieben.Auf meinem Ubuntu 16.04 sind die Leistung und die
tail
Lösung sehr ähnlich. Ich habe eine große Testdatei erstellt mitseq
:tail
Lösung:cat
/ Klammerlösung:Im Moment habe ich allerdings nur eine Ubuntu-VM zur Hand, und ich sah signifikante Unterschiede in den Timings beider, obwohl sie sich alle im selben Baseballstadion befinden.
quelle
tail
, denke aber immer noch, dass dieread
Option sehr cool ist.Wenn ich mich auf meinem System versuche und jedem Befehl ein Präfix voranstelle, erhalte
time
ich die folgenden Ergebnisse:sed:
und Schwanz:
was darauf hindeutet, dass auf meinem System, auf dem mindestens AMD FX 8250 mit Ubuntu 16.04 läuft, Tail deutlich schneller ist. Die Testdatei hatte 10.000 Zeilen mit einer Größe von 540k. Die Datei wurde von einer Festplatte gelesen.
quelle
sed
möglicherweise eine Rolle für dieses Ergebnis. Dies ist die Reihenfolge, in der Sie sie getestet haben.sed
etwa doppelt so schnell.Es gibt keine objektive Art und Weise zu sagen , was besser ist, da
sed
undtail
sind nicht die einzigen Dinge , die laufen auf einem System während der Programmausführung. Viele Faktoren wie Festplatten-E / A, Netzwerk-E / A, CPU-Interrupts für Prozesse mit höherer Priorität - all diese Faktoren beeinflussen, wie schnell Ihr Programm ausgeführt wird.Beide sind in C geschrieben, es handelt sich also nicht um ein Sprachproblem, sondern eher um ein Umweltproblem. Zum Beispiel habe ich eine SSD und auf meinem System dauert dies einige Zeit in Mikrosekunden, aber für dieselbe Datei auf der Festplatte dauert es länger, da die Festplatten erheblich langsamer sind. Auch hier spielt Hardware eine Rolle.
Es gibt ein paar Dinge, die Sie beachten sollten, wenn Sie überlegen, welchen Befehl Sie auswählen sollen:
sed
ist ein Stream-Editor zum Transformieren von Text.tail
dient zur Ausgabe bestimmter Textzeilen. Wenn Sie sich mit Zeilen befassen und diese nur ausdrucken möchten, verwenden Sietail
. Wenn Sie den Text bearbeiten möchten, verwenden Siesed
.tail
hat eine weitaus einfachere Syntax alssed
, verwenden Sie also, was Sie selbst lesen können und was andere lesen können.Ein weiterer wichtiger Faktor ist die Datenmenge, die Sie verarbeiten. Kleine Dateien bieten keinen Leistungsunterschied. Das Bild wird interessant, wenn Sie mit großen Dateien arbeiten. Mit einer BIGFILE.txt von 2 GB können wir feststellen, dass
sed
diese Datei weitaus mehr Systemaufrufe alstail
und erheblich langsamer ausgeführt wird.quelle
tail
besser lesen kannst alssed
- benutze das. Ich persönlich würde verwendenpython
oderawk
eher alssed
weil es komplex werden kann. Wenn Sie sich Sorgen um die Leistung machen, lassen Sie uns die Realität betrachten - Sie sehen hier Ergebnisse in Mikrosekunden. Sie werden keinen Unterschied spüren, es sei denn, es ist eine verdammt große Datei im Gigabyte-Bereich, die Sie zu lesen versuchenawk
Antwort freuen:) ... Meine Frage basierte auf einer anderen AU-Frage und wurde dort nie erwähntawk
. Ich bin damit einverstanden, dass der Zeitunterschied bei kleinen Dateien nominal ist. Ich habe nur versucht, ein paar gute Gewohnheiten zu entwickeln.awk 'NR!=1' input_file.txt
. Es gibt mir das gleiche Ergebnis, etwa 150 Millisekunden, die gleiche Anzahl für beidetail
undsed
. Aber agian, ich verwende SSD, also würde ich sagen, dass es auf die Festplatte und die CPU ankommt, nicht auf den Befehl.sed
weit über 3 Minuten, wohingegentail
nur etwa 20 Sekunden benötigt werden. Das ist noch nicht so groß, definitiv nicht im GB-Bereich.Die beste Antwort berücksichtigte das nicht
> /dev/null
Wenn Sie eine große Datei haben und kein temporäres Duplikat auf Ihrer Festplatte erstellen möchten, versuchen Sie es
vim -c
Bearbeiten: Wenn die Datei größer als der verfügbare Speicher ist,
vim -c
funktioniert dies nicht. Dies scheint nicht intelligent genug zu sein, um die Datei inkrementell zu ladenquelle
Andere Antworten zeigen gut, was besser ist, um eine neue Datei mit fehlender erster Zeile zu erstellen. Wenn Sie eine Datei bearbeiten möchten, anstatt eine neue Datei zu erstellen, ist dies wahrscheinlich
ed
schneller, da keine neue Datei erstellt werden sollte. Aber man muss suchen, wie man eine Zeile mit entfernt,ed
weil ich sie nur einmal verwendet habe.quelle