GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Zählen Sie Zeilen in großen Dateien

Verwenden Sie auf einem Multi-Core-Server GNU parallel, um Dateizeilen parallel zu zählen. Nachdem die Zeilenanzahl jeder Datei ausgegeben wurde, summiert bc alle Zeilenanzahlen.

find . -name '*.txt' | parallel 'wc -l {}' 2>/dev/null | paste -sd+ - | bc

Um Speicherplatz zu sparen, können Sie sogar alle Dateien komprimiert halten. Die folgende Zeile dekomprimiert jede Datei und zählt ihre Zeilen parallel und summiert dann alle Zählungen.

find . -name '*.xz' | parallel 'xzcat {} | wc -l' 2>/dev/null | paste -sd+ - | bc

Gemäß meinem Test kann ich verifizieren, dass die Spark-Shell (basierend auf Scala) viel schneller ist als die anderen Tools (GREP, SED, AWK, PERL, WC). Hier ist das Ergebnis des Tests, den ich an einer Datei mit 23782409 Zeilen durchgeführt habe

time grep -c $ my_file.txt;

real 0m44.96suser 0m41.59ssys 0m3.09s

time wc -l my_file.txt;

echt 0m37.57suser 0m33.48ssys 0m3.97s

time sed -n '$=' my_file.txt;

real 0m38.22suser 0m28.05ssys 0m10.14s

time perl -ne 'END { $_=$.;if(!/^[0-9]+$/){$_=0;};print "$_" }' my_file.txt;

echt 0m23.38suser 0m20.19ssys 0m3.11s

time awk 'END { print NR }' my_file.txt;

real 0m19.90suser 0m16.76ssys 0m3.12s

spark-shell
import org.joda.time._
val t_start = DateTime.now()
sc.textFile("file://my_file.txt").count()
val t_end = DateTime.now()
new Period(t_start, t_end).toStandardSeconds()

res1:org.joda.time.Seconds =PT15S


Ihr begrenzender Geschwindigkeitsfaktor ist die E/A-Geschwindigkeit Ihres Speichergeräts, daher hilft es nicht, zwischen einfachen Zeilenumbruch-/Musterzählprogrammen zu wechseln, da der Unterschied in der Ausführungsgeschwindigkeit zwischen diesen Programmen wahrscheinlich durch langsamere Festplatten/Speicher/unterdrückt wird. was immer du hast.

Aber wenn Sie dieselbe Datei auf mehrere Festplatten/Geräte kopiert haben oder die Datei auf diese Festplatten verteilt ist, können Sie den Vorgang sicherlich parallel ausführen. Ich weiß nichts Genaues über dieses Hadoop, aber vorausgesetzt, Sie können eine 10-GB-Datei von 4 verschiedenen Orten aus lesen, können Sie 4 verschiedene Zeilenzählprozesse ausführen, jeden in einem Teil der Datei, und ihre Ergebnisse zusammenfassen:P>

$ dd bs=4k count=655360 if=/path/to/copy/on/disk/1/file | wc -l &
$ dd bs=4k skip=655360 count=655360 if=/path/to/copy/on/disk/2/file | wc -l &
$ dd bs=4k skip=1310720 count=655360 if=/path/to/copy/on/disk/3/file | wc -l &
$ dd bs=4k skip=1966080 if=/path/to/copy/on/disk/4/file | wc -l &

Beachten Sie die & an jeder Befehlszeile, sodass alle parallel laufen; dd funktioniert wie cat hier, aber lassen Sie uns angeben, wie viele Bytes gelesen werden sollen (count * bs Bytes) und wie viele am Anfang der Eingabe übersprungen werden (skip * bs Bytes). Es funktioniert in Blöcken, daher muss bs angegeben werden als Blockgröße. In diesem Beispiel habe ich die 10-GB-Datei in 4 gleiche Blöcke von 4 KB * 655360 =2684354560 Bytes =2,5 GB partitioniert, einer für jeden Job. Möglicherweise möchten Sie ein Skript einrichten, das dies basierend auf der Größe der Datei für Sie erledigt Datei und die Anzahl paralleler Jobs, die Sie ausführen werden. Sie müssen auch das Ergebnis der Ausführungen zusammenfassen, was ich aufgrund meiner fehlenden Shell-Skriptfähigkeiten nicht getan habe.

Wenn Ihr Dateisystem intelligent genug ist, um große Dateien auf viele Geräte aufzuteilen, z. B. ein RAID oder ein verteiltes Dateisystem oder so, und E/A-Anforderungen automatisch zu parallelisieren, die parallelisiert werden können, können Sie eine solche Aufteilung durchführen, indem Sie viele parallele Jobs ausführen, aber verwenden den gleichen Dateipfad, und Sie haben möglicherweise immer noch einen Geschwindigkeitsgewinn.

BEARBEITEN:Eine andere Idee, die mir eingefallen ist, ist, wenn die Zeilen in der Datei die gleiche Größe haben, können Sie die genaue Anzahl der Zeilen erhalten, indem Sie die Größe der Datei durch die Größe der Zeile dividieren, beides in Bytes. Sie können es fast augenblicklich in einem einzigen Job erledigen. Wenn Sie die mittlere Größe haben und sich nicht genau um die Zeilenanzahl kümmern, aber eine Schätzung wünschen, können Sie dieselbe Operation durchführen und viel schneller ein zufriedenstellendes Ergebnis erzielen als die exakte Operation.


Versuchen Sie:sed -n '$=' filename

Auch Katze ist unnötig:wc -l filename ist genug auf deine jetzige Weise.


Linux
  1. Das Linux-Dateisystem füllt sich, obwohl es keine großen Dateien oder Verzeichnisse gibt

  2. Wie man Zeilen in einer Datei in UNIX/Linux zählt

  3. Zählen Sie die Zeilen aller Dateien im Ubuntu-Verzeichnis

  4. Wie zähle ich Zeilen in einem Dokument?

  5. Verwenden von nc zum Übertragen großer Dateien

Kopieren von Dateien unter Linux

Finden Sie große Dateien in Linux

So teilen Sie große Audiodateien unter Linux

5 Möglichkeiten, die Anzahl der Zeilen in einer Datei zu zählen

So laden Sie große Dateien über den Dateimanager herunter

Linux wc Command – Anzahl der Wörter, Zeilen, Zeichen in einer Datei