web-dev-qa-db-fra.com

compter les lignes dans un fichier compressé

si j'ai un fichier .gz sous Unix qui a un certain nombre de lignes. Comment pourrais-je compter les lignes sur unix sans le décompresser.

37
Vijay

Vous ne pouvez évidemment pas compter les nouvelles lignes si le fichier est toujours compressé.

Mais vous pouvez décompresser dans un flux et compter les nouvelles lignes de ce flux sans jamais écrire le fichier (décompressé) sur le disque. Cela irait quelque chose comme ceci:

zcat file.gz | wc -l

zcat pour decompress & cat, wc pour wordcount. Voir les pages de manuel pour les deux si vous voulez en savoir plus.

EDIT

Si vous n'avez pas zcat, zcat est simplement un autre nom pour gunzip -c.

55
extraneon

Cela semble également fonctionner - grep pour le nombre de fins de ligne dans le fichier

zgrep -Ec "$" file.gz
7
Patrick Wright

Si vous voulez le faire rapidement, je vous recommande d’utiliser "pigz" (IIRC signifie "Parallel Implementation of GZip"). Je viens de faire face à une situation similaire dans laquelle je voulais compter le nombre de lignes dans un tas de fichiers gzipés et voici ma solution:

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

Ce qui m'a donné le nombre de lignes et le fichier qu'il comptait à partir de lignes alternées, en utilisant 8 processeurs. Ça a fonctionné vite!

5
peter

Utilisez cette commande:

gzgrep -c $ filename.gz

La commande gzgrep se comporte de la même façon que grep mais sur les fichiers compressés gzip. Il décompresse le fichier à la volée pour la correspondance regex.

Dans ce cas, -c demande à la commande de générer le nombre de lignes correspondantes et l'expression régulière $ correspond à la fin de la ligne afin qu'elle corresponde à chaque ligne ou au fichier.

Le résultat final est identique à gzip -dc filename.gz | grep -c $.

2
Ravi K M

Si vous êtes d'accord avec une estimation approximative plutôt qu'un décompte exact et que l'extraction de l'ensemble du fichier ou sa compression pour les fins de ligne prendrait beaucoup trop de temps (ce qui était mon cas tout à l'heure), vous pouvez:

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

le nombre de lignes approximatif est alors 1000 * (size of $file) / (size of 1000-line-sample), tant que vos données sont assez homogènes par ligne.

1
James