En fait, j'aimerais avoir la liste de ce qu'il y avait avant le "TIMESTAMP 12/31/2007".
J'ai un fichier log sur plusieurs mois et j'aimerais le découper en plusieurs fichiers avec des dates bien précises......
J'ai pensé à une boucle "while" mais cela implique de charger le fichier en variable donc en mémoire.... Il est trop gros plusieurs centainnes de méga
Je me réponds à moi-même : la même réponse a été donnée plus bas (il me semblait bien avoir lu tous les commentaires pourtant). Ca vaudrait le coup de refaire une petite page de formation à sed, parce que ça tombe dans l'oubli ...
Quelques explications :
On recherche le nombre de lignes du fichier fichier.txt (wc -l) et on ne récupère que le nombre de ligne (cut -f 1 -d ' ').
On y retranche le numéro de la ligne où l'on trouve le motif (grep -n "TIMESTAMP 12/31/2007" (là encore, on ne récupère que le numéro de la ligne, et pas tout le blabla qui s'en suit (cut -f 1 -d ':').
On effectue la soustraction des deux grâce au echo $((A -B +1))
Enfin, on appel tail -n resultat fichier.txt
Voilà, j'espère que ceci répond à la question.
Il y a probablement plus simple, mais au moins, cette commande fonctionne.
Merci Gyro
Effectivement je n'avait pas penser à la commande "tail" certainement à cause du lundi matin :-)
J'ai simplifié ta ligne de commande par la suivante :
tail -`grep -n "TIMESTAMP 12/31/2007" Fichier.log | awk -F: '{print $1}'` Fichier.log
Mais j'ai un problème avec celle ci. En effet la commande tail -34 Fichier.log m'affiche bien les premières 34 lignes du fichier.log.
Dans mon cas le "grep -n "TIMESTAMP 12/31/2007" Fichier.log | awk -F: '{print $1}'" donne 34171. Le tail m'affiche tout le fichier sans s'arrêter à la ligne 34171.
C'est une question de sens, à mon avis....
Si le but est d'afficher les 37141 dernières lignes, il faut en effet utiliser tail, mais si le but est d'afficher les 37141 premières lignes, il faudrait peut-être utiliser head...
Autrement, pour afficher un intervalle, par exemple de la ligne 31542 à la ligne 37141, il faudrait coupler les deux...
Commencer par un head, par exemple, du début du fichier à la ligne 37141, et passer le résultat (que ce soit un pipe ou un fichier temporaire ne changera rien à l'affaire) à tail...
Voilà, en espérant que ça aide.
J'etais pas sur qu'il fallait afficher la ligne en question, mais ce que j'ai donné en solution servait juste de base de travail, et était simplement modifiable.
Pour l'explication :
- /pattern/q va exécuter la command q (quitter) si la ligne correspond au pattern.
- p afficher la ligne.
Dans cet ordre, on ne va pas afficher la ligne qui correspond au pattern, mais si on inverse les deux commandes : sed -ne 'p;/^TIMESTAMP 12\/31\/2007/q'
On imprimer avant de quitter donc on affichera la ligne.
# grep?
Posté par Cheneson Cyril . Évalué à 2.
grep "TIMESTAMP 12/31/2007" mon_fichier
?
[^] # Re: grep?
Posté par dubis . Évalué à 1.
Ce serait trop facile :-)
En fait, j'aimerais avoir la liste de ce qu'il y avait avant le "TIMESTAMP 12/31/2007".
J'ai un fichier log sur plusieurs mois et j'aimerais le découper en plusieurs fichiers avec des dates bien précises......
J'ai pensé à une boucle "while" mais cela implique de charger le fichier en variable donc en mémoire.... Il est trop gros plusieurs centainnes de méga
Merci de votre aide
[^] # Re: grep?
Posté par mac . Évalué à 1.
grep -B`wc -l fichier | sed 's/ .*//'` "TIMESTAMP 12/31/2007" fichier
(il manque clairement une option dans wc pour ne pas afficher le nom de fichier)
[^] # Re: grep?
Posté par Obsidian . Évalué à 4.
sed -e '/TIMESTAMP 12\/31\/2007/ q' < fichier
Sed, ça ne sert pas qu'aux substitutions ...
[^] # Re: grep?
Posté par Obsidian . Évalué à 2.
# Réponse alambiquée :
Posté par Gyro Gearllose . Évalué à 2.
Quelques explications :
On recherche le nombre de lignes du fichier fichier.txt (wc -l) et on ne récupère que le nombre de ligne (cut -f 1 -d ' ').
On y retranche le numéro de la ligne où l'on trouve le motif (grep -n "TIMESTAMP 12/31/2007" (là encore, on ne récupère que le numéro de la ligne, et pas tout le blabla qui s'en suit (cut -f 1 -d ':').
On effectue la soustraction des deux grâce au echo $((A -B +1))
Enfin, on appel tail -n resultat fichier.txt
Voilà, j'espère que ceci répond à la question.
Il y a probablement plus simple, mais au moins, cette commande fonctionne.
[^] # Re: Réponse alambiquée :
Posté par dubis . Évalué à 1.
Effectivement je n'avait pas penser à la commande "tail" certainement à cause du lundi matin :-)
J'ai simplifié ta ligne de commande par la suivante :
tail -`grep -n "TIMESTAMP 12/31/2007" Fichier.log | awk -F: '{print $1}'` Fichier.log
Mais j'ai un problème avec celle ci. En effet la commande tail -34 Fichier.log m'affiche bien les premières 34 lignes du fichier.log.
Dans mon cas le "grep -n "TIMESTAMP 12/31/2007" Fichier.log | awk -F: '{print $1}'" donne 34171. Le tail m'affiche tout le fichier sans s'arrêter à la ligne 34171.
Merci de votre aide
[^] # Re: Réponse alambiquée :
Posté par Gyro Gearllose . Évalué à 3.
Si le but est d'afficher les 37141 dernières lignes, il faut en effet utiliser tail, mais si le but est d'afficher les 37141 premières lignes, il faudrait peut-être utiliser head...
Autrement, pour afficher un intervalle, par exemple de la ligne 31542 à la ligne 37141, il faudrait coupler les deux...
Commencer par un head, par exemple, du début du fichier à la ligne 37141, et passer le résultat (que ce soit un pipe ou un fichier temporaire ne changera rien à l'affaire) à tail...
Voilà, en espérant que ça aide.
[^] # Re: Réponse alambiquée :
Posté par totof2000 . Évalué à 6.
[^] # Re: Réponse alambiquée :
Posté par totof2000 . Évalué à 2.
[^] # Re: Réponse alambiquée :
Posté par mac . Évalué à 1.
(en fait, ça s'arrête 1 ligne trop tôt - mais il y a peut-être une solution simple)
[^] # Re: Réponse alambiquée :
Posté par Pierre Bouteillon . Évalué à 2.
--> solution toute simple: imprimer AVANTde quiter:
awk ' { print $0; if ( $0~/mon texte/ ) { exit } }' monfichier.txt
:-)
[^] # Re: Réponse alambiquée :
Posté par totof2000 . Évalué à 2.
[^] # Re: Réponse alambiquée :
Posté par Étienne . Évalué à 3.
awk '/TIMESTAMP 12\/31\/2007/{print; exit;} {print;}'
En effet, avec awk /pattern/{ code;} exécute le code du bloque si la ligne correspond au pattern.
De même print $0; peut s'abréger en print;
Par rapport à la version en sed, c'est vrai que awk est un peu plus clair, sed ayant des commandes très abrégées.
Étienne
# Avec sed
Posté par Étienne . Évalué à 9.
sed -ne '/^TIMESTAMP 12\/31\/2007/q;p'
Pour l'explication :
- /pattern/q va exécuter la command q (quitter) si la ligne correspond au pattern.
- p afficher la ligne.
Dans cet ordre, on ne va pas afficher la ligne qui correspond au pattern, mais si on inverse les deux commandes :
sed -ne 'p;/^TIMESTAMP 12\/31\/2007/q'
On imprimer avant de quitter donc on affichera la ligne.
Etienne
[^] # Re: Avec sed
Posté par Obsidian . Évalué à 7.
On peut faire plus court en virant l'option n (donc affichage implicite), et donc virer p aussi.
Et tant que l'on y est, on peut donner la commande pour faire l'inverse, soit tout afficher à partir du motif :
sed -ne '/TIMESTAMP 12\/31\/2007/,$ p' < fichier
Voila, comme ça, ça restera dans Google Aide-mémoire ! :-)
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.