[Shell] Lire et écrire dans un fichier

Résolu/Fermé
bezourox Messages postés 729 Date d'inscription vendredi 30 mars 2007 Statut Membre Dernière intervention 19 janvier 2013 - Modifié par bezourox le 3/11/2010 à 15:00
 Niak - 5 nov. 2010 à 10:12
Bonjour,

Je cherche a automatiser une mise à jour de fichier.
Je veux donc lire dans un fichier .txt chaque ligne et les concaténer pour les insérer dans une balise bien précise d'un fichier XML.

J'ai un fichier .txt qui contient cela :

Bonjour 
comment 
tu 
vas 
? 


J'aimerai lire dans ce fichier ligne par ligne pour mettre à jour un deuxième fichier ( .xml) pour qu'il ressemble à cela :

... 
... 
<baliseCCM>Bonjour comment tu vas ? </baliseCCM> 


Je n'ai pas l'habitude de manipuler les fichiers en scripts, donc encore moins manipuler leur contenu...
Si quelqu'un veut donc bien m'aider.

7 réponses

Pour lire ton fichier, rien de plus simple, le petit bout de code suivant te permettra d'afficher chaque ligne une par une (ensuite tu mets ce que tu veux à la place du "echo") :

while read l
do
echo $l
done < monfichier.txt

Pour ce qui est de l'intégration du texte dans un autre fichier, le mieux serais de faire une seule chaîne avec tes différentes lignes :

while read l
do
machaine=$machaine$l
done < monfichier.txt

Ensuite, tu fais ta modification avec un sed par exemple :

sed 's/<baliseCCM><\/baliseCCM>/<baliseCCM>$machaine<\/baliseCCM>/' mondeuxiemefichier.xml

En gros tu devrais pouvoir t'en sortir comme ça. Y'a certainement des modification à faire, j'ai pas tester.
1
En gros la commande sed va te renvoyer ce qui se trouve entre <baliseCCM> et </baliseCCM>. Attention, s'il y a plusieurs fois cette balise dans ton fichier ça risque de faire des trucs bizarres.
Le p signifie qu'il doit imprimer la valeur qu'il trouve (au lieu de la supprimer par exemple avec d).
Pour le \1 je t'avoue que je suis pas très sur, il me semble que c'est pour signifier qu'il faut imprimer la première occurrence trouvé par sed, ce qui se trouve dans (.*) dans notre cas. Je suis pas contre quelques explications plus poussées si quelqu'un en a par contre. :)
Sed est un outil hyper puissant, c'est un peu comme awk, t'as l'impression que tu pourrais faire n'importe quoi avec, mais c'est compliqué à comprendre. Une question d'habitude je suppose.
1
bezourox Messages postés 729 Date d'inscription vendredi 30 mars 2007 Statut Membre Dernière intervention 19 janvier 2013 143
Modifié par bezourox le 3/11/2010 à 17:11
Merci pour ce début.
J'ai réussi à concaténer mes lignes dans un seule avec un espace entre chaque

en revanche j'ai du mal à utiliser sed...

<baliseCCM>vbkvcbjc jcbvjcbvkbv vjfkxvjcx </baliseCCM>


Le but est de mettre à jour la ligne comprise entre ces balises, qui n'est généralement pas vide
0
Effectivement si tu dois mettre à jour la valeur comprise entre tes balises mon exemple ne fonctionne pas. Le mieux serais de récupérer d'abord la valeur, de la concaténer à la nouvelle valeur puis d'utiliser la commande sed que je t'ai donné.

Tu devrais pouvoir récupérer la valeur avec ça :

sed -n -r 's%<baliseCCM>(.*)<\/baliseCCM>%\1%p' mondeuxiemefichier.xml

Je te garantis pas que ça fonctionne du premier coup mais je pense que c'est un bon début.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
bezourox Messages postés 729 Date d'inscription vendredi 30 mars 2007 Statut Membre Dernière intervention 19 janvier 2013 143
Modifié par bezourox le 4/11/2010 à 10:30
Voici le début de mon script :

oldchaine='grep -i domains /cf/conf/config.xml' 
echo Mon ancienne chaine : $oldchaine 

while read ligne 
do 
newchaine=$newchaine$ligne' ' 
done < /var/db/squidGuard/listeblanche/domains 
echo 'Ma nouvelle chaine : <domains>'$newchaine'</domains>'


Le résultat :

# ./maj.sh 
Mon ancienne chaine : <domains>google.com google.fr free.fr pagesjaunes.fr ipadsl.net</domains> 
Ma nouvelle chaine : <domains>google.com google.fr free.fr pagesjaunes.fr ipadsl.net geekzone-clan.org gmail.com </domains>


L'ancienne chaine provient du fichier config.xml que je veux mettre à jour.
La nouvelle chaine provient de la concaténation de plusieurs lignes du fichier domains

Je dois maintenant remplacer l'ancienne par la nouvelle.
Je vais essayer avec ta commande, mais je ne comprends pas tout (les %1 et le /p)
J'ai beau avoir la doc de sed sous les yeux c'est assez complexe
0
bezourox Messages postés 729 Date d'inscription vendredi 30 mars 2007 Statut Membre Dernière intervention 19 janvier 2013 143
4 nov. 2010 à 16:27
Merci pour tes explications.
Je m'en suis sorti avec les commandes suivantes :

sed "/.*<baliseCCM>/s|\(.*[^<]*\)<.*|\1 $newchaine<\baliseCCM>|" /mon/fichier.xml > /mon/fichier/result
mv -f /mon/fichier/result /mon/fichier.xml


Tout ce qui se trouve entre les balises xml </baliseCCM> est remplacé par la valeur contenu dans la variable $newchaine
0
Parfait dans ce cas. Bonne continuation.
0