2010-06-18 9 views
0
@ubuntu:/tmp$ cat one.xml 
<?xml version="1.0" encoding="UTF-8"?> 
    <e2frontendstatus> 
    <e2snrdb> 
     12.10 dB 
    </e2snrdb> 
    <e2snr> 
     75 % 
    </e2snr> 
    <e2ber> 
     0 
    </e2ber> 
    <e2acg> 
     99 % 
    </e2acg> 
    </e2frontendstatus> 
    @ubuntu:/tmp$ sed -n -e 's/.*<e2ber>\([0-9][0-9]*\)<\/e2ber>.*/\1/p' one.xml 
    @ubuntu:/tmp$ 

Je veux obtenir la valeur entre. Mais ça ne marche pas, qu'est-ce que je fais de mal?grep, problème de xml

+0

Ça ne marche pas parce que vous avez des sauts de ligne là-bas ... ce sera faisable avec sed ou awk, j'en suis sûr, mais serait probablement plus heureux en perl ... avez-vous cette disponibilité? – Cascabel

+0

Le problème est que sed applique des expressions régulières à une ligne à la fois. Puisque les et sont sur des lignes différentes, ils ne correspondent pas à l'expression. Pouvez-vous changer le format de fichier pour quelque chose comme ? Ensuite, vous pourriez être en mesure d'identifier la ligne plus facilement. –

+0

L'autre question que nous devrions poser est votre condition exacte. Je comprends que vous avez des ressources limitées, donc vous n'allez pas analyser complètement le XML, donc votre robustesse sera limitée. Vous pouvez au moins compter sur le fichier XML ne faisant rien de trop fou, j'espère. – Cascabel

Répondre

1

Quelle est la valeur que vous cherchez? Savez-vous que le grep de Linux a des paramètres de ligne de commande "Après contexte" et "Avant le contexte"? C'est peut-être la façon la plus simple d'extraire l'information que vous cherchez.

Par exemple, si vous essayez d'obtenir la valeur après la ligne, vous pourriez faire quelque chose comme ceci:

$ grep -A1 "<e2ber>" | tail -1 
+0

Simple, et fonctionne comme un charme !! Merci beaucoup! – Peter

2

Le traitement de xml avec des expressions régulières n'est pas une très bonne idée, vous pourriez vouloir regarder dans un outil de ligne de commande comme xmlstarlet pour faire cette extraction.

xmlstarlet sel -t -v "//e2ber" one.xml 
+1

Merci pour la réponse, mais je lance cette petite commande sur un système embarqué (récepteur satellite), où il n'est pas possible d'exécuter xmlstarlet (qui est un très bel outil): /. Toutes les autres commandes linux sont disponibles, grep, sed .. – Peter

+0

Pouvez-vous installer xmllint? – reinierpost

+0

reinerpost: Rien: | – Peter

1

Si vous avez la possibilité grep -A mentionné dans la réponse ci-dessus, et la commande Unix tr sur votre système, vous pouvez faire quelque chose de raisonnablement robuste.

Cette commande doit obtenir la valeur appropriée:

grep -A2 '<e2ber>' one.xml | \ 
    tr -d '\n' | \ 
    sed -n -E -e 's/.*<e2ber>[[:blank:]]*([0-9][0-9]*)[[:blank:]]*<\/e2ber>.*/\1/p' 

Cela devrait fonctionner si le fichier XML est formaté comme <e2ber>0</e2ber> ou

<e2ber> 
    0 
</e2ber> 

Le grep attraper suffisamment de lignes pour inclure la fermeture tag, le tr fera une longue ligne, et le sed va extraire la valeur. J'ai mis à jour l'expression régulière dans le sed pour ignorer les espaces autour de la valeur.

Cela peut toujours poser problème si le fichier XML est à double interligne, par exemple.

<e2ber> 

0 

</e2ber> 

Vous pouvez contourner ce problème en exécutant le fichier XML à travers tr -s '\n' au préalable. Cela permettra de compacter plusieurs nouvelles lignes en une seule nouvelle ligne.