Récupérer variables entre plusieurs balises sur même ligne

spctoma -  
 spctoma -
Bonjour,

Je dispose dans mon script d'une variable "fichedesc" qui contient la chaine de caractère suivante :

fichedesc="<mId>AHBU30008X</mId> <mDesc>Descr. de la fiche</mDesc> <mPages>3</mPages>"

Pour récupérer le contenu des balises mDesc et mPages, je fais :
mDesc='echo $fichedesc | sed -n '/<mDesc>.*<\/mDesc>/s/[^>]*>\([^<]*\)<.*/\1/p''
mPages='echo $fichedesc | sed -n '/<mPages>.*<\/mPages>/s/[^>]*>\([^<]*\)<.*/\1/p''


Mais j'obtiens : AHBU30008X dans mDesc et mPages ...
Je ne comprends pas pourquoi mon sed ne récupère que le contenu des premières balises.

Pourriez vous m'aider s'il vous plaît ?

Merci d'avance

4 réponses

  1. Utilisateur anonyme
     
    while read -r line
    do
       case "$line" in
          \<Fiche\>) fic=1; toBsent="";;
          \</Fiche\>) echo "envoi \"$toBsent\" >> fichier.js"; fic=0;;
       esac
       test $fic -eq 1 && case $line in
             *mEcsIdCode*|*mType*|*mNbPages*|*mDescription*) line="${line#*>}"
                toBsent="$toBsent
    ${line%%<*}";;
          esac
    done < $tonFichier

    par contre, il n'y a pas de d'indicateur de progression.
    c'est probablement perfectible (je ne comprend pas tout ton code, il me pique un peu les yeux)

    si le fichier est vraiment gros, ça s'adaptera facilement en awk.
    1
  2. zipe31 Messages postés 34620 Date d'inscription   Statut Contributeur Dernière intervention   6 501
     
    Salut,

    Parce que le "/<mDesc>.*<\/mDesc>/" ne sert à rien dans ta syntaxe. On utilise un motif que pour cibler une ligne particulière dans un fichier, mais toi tu n'as qu'une ligne à traiter, donc que tu mettes "/<mPages>.*<\/mPages>/" ou "/<mDesc>.*<\/mDesc>/", c'est toujours la même ligne qui est traitée dans sa totalité et non à partir du motif comme tu l'espérais ;-\

    $ sed -n 's/[^>]*>\([^<]*\)<.*/\1/p' <<<${fichedesc}
    AHBU30008X
    
    $ sed -n 's/.*<mPages>\([^<]*\)<.*/\1/p' <<<${fichedesc}
    3

    0
    1. zipe31 Messages postés 34620 Date d'inscription   Statut Contributeur Dernière intervention   6 501
       
      On va même simplifié, enfin raccourcir la syntaxe, mais il faut impérativement que le motif cible soit le dernier sur la ligne :

      $ sed -n 's/.*>\b\([^<]*\)<.*/\1/p' <<<${fichedesc}
      3
      0
    2. spctoma
       
      J'avais fini par utliser la méthode suivante :
      mDescriptionTemp=${fichedesc%%<mDescription*}
      mDescription=${mDescriptionTemp##*mDescription>}
      qui faisait l'affaire, mais ta solution étant plus propre, je vais l'utiliser ! Merci beaucoup en tout cas
      0
    3. Utilisateur anonyme
       
      Si tu peux éviter d'appeler une commande externe, c'est quand même mieux.
      Tu devrais gagner en performance en n'utilisant que les substitutions de paramètres.

      L'usage d'une variable temporaire n'est pas indispensable.
      0
  3. spctoma
     
    J'utilise la méthode de zipe31 (merci à lui) :
    mDescription='echo $fichedesc | sed -n 's/.*mDescription>\b\([^<]*\)<.*/\1/p''
    mNbPages='echo $fichedesc | sed -n 's/.*mNbPages>\b\([^<]*\)<.*/\1/p''


    Qui marche bien. qqchosequicommenceparQ tu penses qu'en terme de performance il vaut mieux utiliser quoi ? Etant donné que j'ai 10 000 variables $fichedesc à traiter, je suis soucieux de la perf :)

    Dans une boucle je fais à chaque fois :
    fichedesc='sed -n "/<mEcsIdCode>"$fiche"<\/mEcsIdCode>/,/Fiche>/p" $lienFicDescFicheLight'

    puis je récupère le contenu des balises <mNbPage> et <mDescription>

    J'ai un fichier xml $lienFicDescFiches de la forme suivante, avec 10 000 <Fiche> soit au total plus de 130 000 lignes :
    <Fiche>
    <mEcsIdCode>id de la fiche</mEcsIdCode>
         <balise1> </balise1>
        <balise 2> </balise 2>
        <mType> </mType>
        <mNbPages> </mNbPages>
        <mDescription> </mDescription>
    </Fiche>


    Pensez vous que je puisse optimiser mieux les performences ? (c'est assez long à tourner) :

    lienFicDescFicheLight=./temp_FicDescFichesLight.xml
            #Je créée un fichier xml temporaire ne contenant que les balises que je veux récupèrer
    	egrep -i '(mEcsIdCode|mType|mNbPages|mDescription|</Fiche>)' $lienFicDescFiches > $lienFicDescFicheLight
    	
           #J'ai la liste des fiches qui m'intéressent dans le fichier "temp_liste_xml_fiches"
    	for fiche in 'cat ./temp_liste_xml_fiches | sort | uniq | tr -d ' ''
    	do
    		fichedesc='sed -n "/<mEcsIdCode>"$fiche"<\/mEcsIdCode>/,/Fiche>/p" $lienFicDescFicheLight'
                    #Traitement de la DESCRIPTION :
    		#mDescriptionTemp=${fichedesc%%</mDescription*}
    		#mDescription=${mDescriptionTemp##*mDescription>}
    		mDescription='echo $fichedesc | sed -n 's/.*mDescription>\b\([^<]*\)<.*/\1/p''
    		echo 'mDescription["'$fiche'"]="'$mDescription'";' >> ./images/function.js
    		#Traitement du NB DE PAGES :
                    #mNbPagesTemp=${fichedesc%%</mNbPages*}
    		#mNbPages=${mNbPagesTemp##*mNbPages>}
    		mNbPages='echo $fichedesc | sed -n 's/.*mNbPages>\b\([^<]*\)<.*/\1/p''
    		echo 'mNbPages["'$fiche'"]='$mNbPages';' >> ./images/function.js
    		#Traitement du TYPE :
    		#mTypeTemp=${fichedesc%%</mType*}
    		#mType=${mTypeTemp##*mType>}
    		mType='echo $fichedesc | sed -n 's/.*mType>\b\([^<]*\)<.*/\1/p''
    		echo 'mType["'$fiche'"]="'$mType'";' >> ./images/function.js
    		
    		echo -ne "\rIndexage des fiches pour la fonction recherche: ${currentFiche}/${nombreFiches} (${progression}%)\r" | awk '{printf("%s", $0)}'
    	done
    0
  4. spctoma
     
    Désolé si ça pique les yeux, je ne suis pas un expert en shell, j'arrive juste à faire marcher quelques trucs :)

    Ce sont des déclarations de tableaux en javascript que je veux exporter pour chaque balises

    J'ai adapté ce que tu m'as donné et ... ça marche nickel ! Et c'est bien plus rapide qu'avant.
    Merci beaucoup :)

    while read -r line
    		do
    		  case "$line" in
    		      \<Fiche\>)
    				fic=1; toBsent="";;
    		      \</Fiche\>)
    				echo $toBsent >> ./images/liste_mop.js
    				fic=0;;				
    		  esac
    
    		  test $fic -eq 1 && case $line in
    			*mEcsIdCode*)
    			line="${line#*>}"
    			fiche=${line%%<*};;
    			
    			  *mType*)
    			  line="${line#*>}"
    			  toBsent="$toBsent
    		mType['$fiche']='${line%%<*}'; ";;
    
    			  *mNbPages*)
    			  line="${line#*>}"
    			  toBsent="$toBsent
    		mNbPages['$fiche']='${line%%<*}'; ";;
    
    			  *mDescription*)
    			  line="${line#*>}'"
    			  toBsent="$toBsent
    		mDescription['$fiche']='${line%%<*}'; ";;
    		      esac
    		done < $lienFicDescFiches	


    ça me donne le fichier javascript sous la forme :

    mDescription['878AKJ9918']='bla bla '; mType['878AKJ9918']='truc'; mNbPages['878AKJ9918']='3';
    mDescription['4516HJ4952']='bla bla '; mType['4516HJ4952']='truc'; mNbPages['4516HJ4952']='3';
    0