Parser une ligne avec des clés=valeurs contenant des espaces (csh)

Le
Kevin Denis
Bonjour,

je dois parser des lignes de log construites sur un schéma clé=valeur
ressemblant à:

idªA type»B valueÌC msg="aaa bbb ccc ddd eee" value2=xxx
value3="eee eee eee"
idª2 type»2 valueÌ2 value2=xx2 value3="eee eee eee"
etc

Les lignes n'ont pas forcément toutes les clés renseignées.

Je souhaite parser ces lignes pour n'en conserver qu'une partie, par
exemple msg, id, value2 et value3. Je ne trouve pas de moyen simple
pour parser ces lignes. Mon plus gros problème vient des espaces dans
certaines valeurs et de l'absence de clés dans d'autres.
J'en ai besoin pour faire:

tail -f /var/log/my_log | parse_line.sh

C'est sous FreeBSD, avec csh (pas de bash disponible) et les utilitaires
classiques (sed, cut, awk, etc..)

Merci
--
Kevin
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Nicolas George
Le #26345881
Kevin Denis , dans le message
Mon plus gros problème vient des espaces dans
certaines valeurs et de l'absence de clés dans d'autres.



Donc il te faut la description précise et détaillée de la syntaxe.

C'est sous FreeBSD, avec csh (pas de bash disponible) et les utilitaires
classiques (sed, cut, awk, etc..)



Donc entre autres c99.
Lucas Levrel
Le #26345932
Le 25 mars 2015, Kevin Denis a écrit :

idªA type»B valueÌC msg="aaa bbb ccc ddd eee" value2=xxx
value3="eee eee eee"
idª2 type»2 valueÌ2 value2=xx2 value3="eee eee eee"
etc...

Les lignes n'ont pas forcément toutes les clés renseignées.

Je souhaite parser ces lignes pour n'en conserver qu'une partie, par
exemple msg, id, value2 et value3. Je ne trouve pas de moyen simple
pour parser ces lignes. Mon plus gros problème vient des espaces dans
certaines valeurs et de l'absence de clés dans d'autres.

echo valueÌC msg="aaa bbb ccc ddd eee" value2=xxx


| egrep -o 'msg="[A-Za-z ]*"|msg=[A-Za-z]*'
msg="aaa bbb ccc ddd eee"

echo valueÌC msgªa value2=xxx


| egrep -o 'msg="[A-Za-z ]*"|msg=[A-Za-z]*'
msgªa

Est-ce que ça aide ?

--
LL
Ἕν οἶδα ὅτι οὐδὲν οἶδα (Σωκράτης)
Kevin Denis
Le #26345944
Le 25-03-2015, Lucas Levrel
Je souhaite parser ces lignes pour n'en conserver qu'une partie, par
exemple msg, id, value2 et value3. Je ne trouve pas de moyen simple
pour parser ces lignes. Mon plus gros problème vient des espaces dans
certaines valeurs et de l'absence de clés dans d'autres.



echo valueÌC msg="aaa bbb ccc ddd eee" value2=xxx


| egrep -o 'msg="[A-Za-z ]*"|msg=[A-Za-z]*'
msg="aaa bbb ccc ddd eee"

echo valueÌC msgªa value2=xxx


| egrep -o 'msg="[A-Za-z ]*"|msg=[A-Za-z]*'
msgªa

Est-ce que ça aide ?



$ egrep
egrep: Command not found.

J'ai quand même grep -E qui me permet de faire ce genre de choses:
grep -E -o 'msg="[A-Za-z0-9 -.:]*"|value2=[a-z]*'

Ca marche bien, mais l'ensemble des clés choisies sont affichées sur
plusieurs lignes:

tail log | grep -E -o 'msg="[A-Za-z0-9 -.:]*"|value2=[a-z]*'
msg="XXX YYY"
value2=ssh
msg="aaa bbb"
value2«c

Et je retombe dans un problème : je peux concaténer les lignes
en une seule avec un | sed 'N;s/n/ /' ou équivalent avec awk, mais comme
certaines lignes de log n'ont pas toutes les clés, cela finit par tout
décaler :-/

Ca va finir avec un oneliner abominable du genre:
tail -f log | grep (...) | tr 'n' ' ' | sed s/msg/µmsg/g | tr 'µ' 'n'

ou mieux, un:
ssh server tail -f log | script_local_evolué

Merci pour l'idée en tout cas :)
--
Kevin
Lucas Levrel
Le #26346007
Le 25 mars 2015, Kevin Denis a écrit :

$ egrep
egrep: Command not found.



:-)

J'ai quand même grep -E qui me permet de faire ce genre de choses:
grep -E -o 'msg="[A-Za-z0-9 -.:]*"|value2=[a-z]*'

Ca marche bien, mais l'ensemble des clés choisies sont affichées sur
plusieurs lignes:

tail log | grep -E -o 'msg="[A-Za-z0-9 -.:]*"|value2=[a-z]*'
msg="XXX YYY"
value2=ssh
msg="aaa bbb"
value2«c



Est-ce qu'un truc comme ça est possible en csh :
--- parse_line.sh ---
while read LINE
do
MSG=$(echo $LINE | grep -E -o ...)
VALUE2=$(echo $LINE | ...)
...
done
echo $MSG $VALUE2 ...
---------------------
?

(Tu as bien dit que tu pouvais envoyer le log dans un script, tu n'es pas
contraint à un one-liner ?)

--
LL
Ἕν οἶδα ὅτι οὐδὲν οἶδα (Σωκράτης)
Nicolas George
Le #26346013
Lucas Levrel , dans le message
while read LINE



Ça commence mal si la ligne contient des backslashes.

do
MSG=$(echo $LINE | grep -E -o ...)



Et ça continue de même.

Des scripts qui ne marchent pas, on peut en faire en csh aussi, oui, pas de
problème.
Kevin Denis
Le #26346095
Le 25-03-2015, Lucas Levrel
J'ai quand même grep -E qui me permet de faire ce genre de choses:
grep -E -o 'msg="[A-Za-z0-9 -.:]*"|value2=[a-z]*'

Ca marche bien, mais l'ensemble des clés choisies sont affichées sur
plusieurs lignes:

tail log | grep -E -o 'msg="[A-Za-z0-9 -.:]*"|value2=[a-z]*'
msg="XXX YYY"
value2=ssh
msg="aaa bbb"
value2«c



Est-ce qu'un truc comme ça est possible en csh :
--- parse_line.sh ---
while read LINE



J'avais tenté, mais le while read ne semble pas exister en csh:
http://www.linuxquestions.org/questions/programming-9/csh-while-read-738708/
question: Is there an equivalent in csh to bash's while read cariable list?
Answer: AFAIK, the answer is no.

(Tu as bien dit que tu pouvais envoyer le log dans un script, tu n'es pas
contraint à un one-liner ?)



Non. C'est une appliance Netasq, donc un FreeBSD dedans. Je pensais qu'il
y avait moyen d'obtenir un one-liner :) mais je vais faire un script.
--
Kevin
Benoit Izac
Le #26346211
Bonjour,

le 26/03/2015 à 10:06, Kevin Denis a écrit dans le message

Est-ce qu'un truc comme ça est possible en csh :
--- parse_line.sh ---
while read LINE



J'avais tenté, mais le while read ne semble pas exister en csh:
http://www.linuxquestions.org/questions/programming-9/csh-while-read-738708/
question: Is there an equivalent in csh to bash's while read cariable list?
Answer: AFAIK, the answer is no.



Donc pourquoi utiliser csh (tcsh) plutôt que sh (ash il me semble) ?

--
Benoit Izac
Lucas Levrel
Le #26346344
Le 25 mars 2015, Nicolas George a écrit :

while read LINE



Ça commence mal si la ligne contient des backslashes.

do
MSG=$(echo $LINE | grep -E -o ...)



Et ça continue de même.



Sans doute. Comme les points de suspension le suggèrent, ce sont des
pistes.

En l'occurence, seul l'OP sait ce qu'il est susceptible d'y avoir.


Des scripts qui ne marchent pas, on peut en faire en csh aussi, oui, pas de
problème.



Ouaip, c'est comme les réponses inutiles, on peut les faire dans toutes
les langues.


--
LL
Ἕν οἶδα ὅτι οὐδὲν οἶδα (Σωκράτης)
Nicolas George
Le #26346348
Lucas Levrel , dans le message
Ouaip, c'est comme les réponses inutiles



Souligner les erreurs classiques dans la rédaction de scripts shell, erreurs
classiques qui conduisent régulièrement à des pertes de données
accidentelles ou des trous de sécurité...

À toi de voir si tu considères ça comme inutile.
Paul Gaborit
Le #26346366
À (at) 27 Mar 2015 12:52:36 GMT,
Nicolas George
Lucas Levrel , dans le message
Ouaip, c'est comme les réponses inutiles



Souligner les erreurs classiques dans la rédaction de scripts shell, erreurs
classiques qui conduisent régulièrement à des pertes de données
accidentelles ou des trous de sécurité...

À toi de voir si tu considères ça comme inutile.



Plutôt que de souligner les erreurs, il serait bon de proposer le moyen
de ne pas les faire !

Et le premier moyen, bien connu de tous ceux qui développent proprement
en shell, est de ne pas utiliser (t)csh comme shell pour les scripts.

Il vaut mieux choisir sh (celui de FreeBSD n'est pas bash) ce qui oblige
à faire du shell standard POSIX. Ou alors choisir bash, ksh ou zsh qui
sont bien plus puissants mais dont la disponibilité n'est pas garantie
partout.

--
Paul Gaborit -
Publicité
Poster une réponse
Anonyme