Comment zgrep la dernière ligne d'un fichier gz sans queue
Voici mon problème, j'ai un ensemble de grands gz
les fichiers journaux, les toutes premières infos sur la ligne est un datetime texte, par exemple: 2014-03-20 05:32:00.
J'ai besoin de vérifier ce que l'ensemble de fichiers journaux détient des données spécifiques.
Pour l'init, je fais simplement un:
'-query-data-'
zgrep -m 1 '^20140320-04' 20140320-0{3,4}*gz
MAIS COMMENT faire la même chose avec la dernière ligne, sans processus de l'ensemble de fichiers comme le ferait avec zcat (trop lourd):
zcat foo.gz | tail -1
Informations supplémentaires, ces journaux sont créés avec les données de l'enregistrement initial, donc si je veux les journaux de requêtes à 14:00:00 je recherche, également, dans des fichiers créés AVANT 14:00:00, un dossier sera créé à 13:50:00 et fermé à 14:10:00.
est-il un motif sur le programme d'éradication de mach à la fin du fichier, comme il le fait pour la fin de la ligne
$
Le problème est que les données compressées est difficile de processus en arrière. Flux des algorithmes de compression comme LZW sont basés sur des algorithmes adaptatifs, et le lecteur devra traiter les données compressées afin d'apprendre les compressions comme il va.
Pouvez-vous augmenter la fréquence sur
logrotate
(ou quelle que soit la compresse les fichiers journaux) afin d'avoir de plus petits fichiers compressés à la recherche? Cela va réduire la charge de la décompression du fichier, qui est une donnée.Merci, mais je ne pense pas que c'est une suffisamment bonne réponse. En attendant, je tiens à vous diriger vers ces pages stackoverflow.com/questions/429987/... stackoverflow.com/questions/236414/... lh3.github.io/2014/07/05/random-access-à-zlib-comprimé-fichiers
OriginalL'auteur Rodrigo Gurgel | 2014-03-20
Vous devez vous connecter pour publier un commentaire.
La solution la plus simple serait de modifier votre journal de rotation pour créer des fichiers plus petits.
La deuxième solution la plus simple serait d'utiliser un outil de compression qui prend en charge l'accès aléatoire.
Des projets comme dictzip, BGZF, et le csio chaque ajouter synchronisation rincer points à divers intervalles dans compressée par gzip de données qui vous permettent de rechercher dans un programme de connaissance de cette information supplémentaire. Bien qu'il existe dans la norme, la vanille
gzip
ne pas ajouter de tels marqueurs, soit par défaut ou en option.Les fichiers compressés par ces random-access-friendly utilitaires sont légèrement plus grandes (par exemple, de 2 à 20%) en raison des marqueurs eux-mêmes, mais entièrement en charge la décompression avec
gzip
ou d'une autre utilité qui n'est pas au courant de ces marqueurs.Vous pouvez en apprendre plus à cette question sur d'accès aléatoire dans divers formats de compression.
Il y a aussi un "Fustigé la Bioinformatique" blog de Peter Bite avec plusieurs posts sur ce sujet, y compris:
Expériences avec
xz
xz
(un LZMA format de compression) a effectivement accès aléatoire de l'assistance, un bloc de niveau, mais vous ne recevrez qu'un seul bloc avec les valeurs par défaut.De création de fichier
xz
pouvez concaténer plusieurs archives ensemble, dans ce cas, chaque archive aurait son propre bloc. Le GNUsplit
pouvez le faire facilement:Cela dit
split
de briserbig.log
en 50 morceaux (avant de compression) et d'exécuter un par un à traversxz -c
, qui sort le comprimé morceau sur la sortie standard. Nous récoltons alors que la sortie standard dans un seul fichier nommébig.log.sp.xz
.De le faire sans GNU, vous auriez besoin d'une boucle:
Analyse
Vous pouvez obtenir la liste de bloquer les décalages avec
xz --verbose --list FILE.xz
. Si vous voulez le dernier bloc, vous avez besoin de sa taille compressée (colonne 5) plus de 36 octets pour les frais généraux (trouvé en comparant la taille dehd big.log.sp0.xz |grep 7zXZ
). Fetch bloc à l'aide d'tail -c
et le tuyau qui par le biais dexz
. Depuis la question ci-dessus veut la dernière ligne du fichier, j'ai ensuite tuyau à traverstail -n1
:Note de côté
Version 5.1.1 introduction du support pour le
--block-size
drapeau:Cependant, je n'ai pas été en mesure d'extraire un bloc spécifique, car il n'inclut pas les en-têtes complets entre les blocs. Je suppose que c'est pas évident de faire à partir de la ligne de commande.
Expériences avec
gzip
gzip
prend également en charge la concaténation. J' (brièvement) essayé d'imiter ce processus pourgzip
sans un peu de chance.gzip --verbose --list
ne donnent pas assez d'informations et il semble que les en-têtes sont trop variables pour trouver.Cela nécessiterait l'ajout de la synchronisation rincer les points, et, depuis, leur taille varie en fonction de la taille de la dernière mémoire tampon lors de la précédente compression, c'est trop dur à faire sur la ligne de commande (utilisation dictzip ou l'autre des outils en question).
Je n'ai
apt-get install dictzip
et a joué avec dictzip, mais juste un peu. Il ne fonctionne pas sans arguments, la création d'un (énorme!).dz
archive que nidictunzip
nigunzip
pourrait comprendre.Expériences avec
bzip2
bzip2
ont des en-têtes que nous pouvons trouver. C'est encore un peu brouillon, mais ça fonctionne.Création
C'est exactement comme les
xz
procédure ci-dessus:Je tiens à noter que c'est considérablement plus lent que
xz
(48 min pour bzip2 vs 17 min pour xz vs 1 min pourxz -0
) ainsi que de beaucoup plus grandes (97M pour bzip2 vs 25M pourxz -0
vs 15M pour xz), au moins pour mon test fichier journal.Analyse
C'est un peu plus difficile parce que nous n'avons pas le gentil de l'index. Nous avons à deviner où aller, et nous devons nous pencher du côté de la numérisation de trop, mais avec un énorme fichier, nous serions tout de même sauver des I/O.
Je suppose que pour ce test a été 50000000 (de l'origine de 52428800, un pessimiste suppose que ce n'est pas assez pessimiste pour, par exemple, H. 264 vidéo.)
Cela dure depuis 50 millions d'octets, trouve le binaire offset de la dernière BZIP2-tête, soustrait qu'à partir de l'estimation de la taille, et tire que le nombre d'octets off de la fin du fichier. Juste que la partie est décompressé et jeté dans
tail
.Parce que cela a à interroger le fichier compressé à deux reprises et a un contrôle supplémentaire (le
grep
appel cherchant l'en-tête, qui examine l'ensemble deviné espace), c'est une solution sous-optimale. Voir également la section ci-dessous sur la façon de ralentirbzip2
est vraiment.Point de vue
Compte tenu de la rapidité
xz
est, il est facilement le meilleur pari; à l'aide de son option la plus rapide (xz -0
) est assez rapide pour compresser ou décompresser et crée un fichier plus petit quegzip
oubzip2
sur le fichier journal j'ai été le tester avec. D'autres tests (ainsi que de diverses sources en ligne) suggèrent quexz -0
est préférable debzip2
dans tous les scénarios.Synchronisation tests n'ont pas été complet, je n'ai pas tout moyen et le cache disque est en cours d'utilisation. Encore, ils ont l'air correct; il y a une très petite quantité de surcharge de
split
plus lancement de 145 cas de compression plutôt qu'un seul (cela peut même être un net gain si elle permet à un non-multithread utilitaire de consommer plusieurs threads).dictzip -t file.dz
(en-tête simple vérification): soit il échoue immédiatement ou succède immédiatement.OriginalL'auteur Adam Katz