Zeilen in einer komprimierten Datei zählen

42

Wenn ich eine .gz-Datei unter Unix habe, die eine bestimmte Anzahl von Zeilen hat. Wie könnte ich die Zeilen unter Unix zählen, ohne sie zu dekomprimieren?

Vijay
quelle
Ohne das Archiv zu extrahieren, können Sie die Zeilen nicht zählen.
zoli2k

Antworten:

60

Sie können natürlich keine Zeilenumbrüche zählen, wenn die Datei noch komprimiert ist.

Sie können jedoch in einen Stream dekomprimieren und die Zeilenumbrüche in diesem Stream zählen, ohne die (dekomprimierte) Datei jemals auf die Festplatte schreiben zu müssen. Das würde ungefähr so ​​gehen:

zcat file.gz | wc -l

zcat zum dekomprimieren & cat, wc für wordcount. Weitere Informationen finden Sie in den Manpages zu beiden.

BEARBEITEN

Wenn Sie nicht über zcat verfügen, ist zcat nur ein anderer Name für gunzip -c.


quelle
7
Auf Unices, von denen gzipman sich unterscheidet compress, möchte man gzcat.
Coneslayer
7

Dies scheint auch zu funktionieren - grep für die Anzahl der Zeilenenden in der Datei

zgrep -Ec "$" file.gz
Patrick Wright
quelle
Dies gibt eine andere (viel höhere) Antwort für mich als die wc -l
Weiterleitung
5

Wenn Sie es schnell erledigen möchten, empfehle ich die Verwendung von 'pigz' (wobei IIRC für "Parallel Implementation of GZip" steht). Ich hatte gerade eine ähnliche Situation, in der ich die Anzahl der Zeilen in einer Reihe von gzip'ed-Dateien zählen wollte, und hier war meine Lösung:

for x in *.gz; do unpigz -p 8 -c $x | wc -l && echo $x; done

Das gab mir die Anzahl der Zeilen und die Datei, von der auf abwechselnden Zeilen mit 8 Prozessoren gezählt wurde. Es lief schnell!

Peter
quelle
1
Oder wenn unpigz nicht verfügbar ist, einfach mitfor x in *.fastq.gz; do zcat "$x" | wc -l && echo $x; done
Calimo 20.11.15
2

Verwenden Sie diesen Befehl:

gzgrep -c $ filename.gz

Der Befehl gzgrepverhält sich wie grepbei komprimierten gzip-Dateien. Es dekomprimiert die Datei im laufenden Betrieb für den regulären Ausdruck.

In diesem Fall wird -cder Befehl angewiesen, die Anzahl der übereinstimmenden Zeilen auszugeben, und der reguläre Ausdruck $stimmt mit dem Zeilenende überein, sodass er mit jeder Zeile oder Datei übereinstimmt.

Das Endergebnis ist identisch mit gzip -dc filename.gz | grep -c $.

Ravi KM
quelle
Ist gzgrepes auf anderen Systemen als Solaris verfügbar?
Pabouk
1
Nein. Auf anderen Systemen lautet der Befehl zgrep -c $ filename.gz
Ravi KM
1
Man könnte zwar intuitiv denken, dass dies besser ist als zcat + wc, aber wenn ich sie zeitlich einstelle, nehmen sie sich die gleiche Zeit.
ngọcminh.oss
1

Wenn Sie mit einer groben Schätzung anstatt einer exakten Zählung einverstanden sind und die gesamte Datei tatsächlich zu extrahieren oder sie für Zeilenenden zu zerkleinern, würde dies viel zu lange dauern (was gerade meine Situation war), können Sie:

zcat "$file" | head -1000 > 1000-line-sample.txt
ls -ls 1000-line-sample.txt "$file"

dann ist die ungefähre Zeilenzahl 1000 * (size of $file) / (size of 1000-line-sample), solange Ihre Daten pro Zeile ziemlich homogen sind.

James
quelle
0

gzip -cd <file.gz> | wc -l

Das hat bei mir funktioniert.

Prashanth
quelle