# Sed et variable bash

**URL:** <https://www.debian-fr.org/t/sed-et-variable-bash/9098>\
**Category:** Programmation\
**Created:** [Février 20, 2016, 4:19 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098 "2016-02-20T16:19:30Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Aeris1](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/b4bc9f/32.png) [@Aeris1](https://www.debian-fr.org/u/Aeris1)\
**Post date:** [Février 20, 2016, 4:19 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098/1 "2016-02-20T16:19:30Z")

</div>

Bonjour à tous.  
J’ai un petit problème avec sed, et j’espère que quelqu’un ici pourra m’aiguiller vers une solution.

J’ai un fichier contenant une liste de valeurs, sous la forme:`nom1:valeur1
nom2:valeur2
...`  
Je dois ensuite traiter ligne par ligne ce fichier avec un script bash, et pour cela, j’ai besoin de récupérer nomX et valeurX dans des variables bash.  
La regexp est l’enfance de l’art ((._):(._)), mais comment récupérer les parenthèses capturantes dans 2 variables bash?  
J’ai bien tenté un`sed 's/\(.*\):\(.*\)/NOM=\1 VALEUR=\2/p' | sh`mais un`echo $NOM $VALEUR`me renvoie irrémédiablement une chaîne vide (je pense que cela vient du fait que j’appelle sh, et donc que les variables ne sont définies que dans le sous-shell temporaire)…

Quelqu’un aurait-il une piste?

---

<div class="post-metadata">

**Author:** ![thialme](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/t/50afbb/32.png) [@thialme](https://www.debian-fr.org/u/thialme)\
**Post date:** [Février 20, 2016, 4:19 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098/2 "2016-02-20T16:19:30Z")

</div>

Quelque chose comme cela :

```auto
thialme@sid:~$ cat tmp 
chemin1:1
chemin2:2
chemin3:3

thialme@sid:~$ awk -F : '{ print $1 " " $2*3 }' tmp 
chemin1 3
chemin2 6
chemin3 9
```

Cf post précédent sur sed aussi.

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 4:19 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098/3 "2016-02-20T16:19:30Z")

</div>

`NOM=`sed -e "s/\(.\):.*$/\1/g"`
VALEUR=`sed -e "s/^.*:\(.\)/\1/g"``  
Mais du coup tu peut pas travailler sur des flux.

Le problème c’est qu’avec ta technique même si un export par exemple fonction tu ne va récupérer que la dernière valeur (avec mon code c’est une liste que tu chope).

---

<div class="post-metadata">

**Author:** ![Aeris1](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/b4bc9f/32.png) [@Aeris1](https://www.debian-fr.org/u/Aeris1)\
**Post date:** [Février 20, 2016, 4:19 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098/4 "2016-02-20T16:19:31Z")

</div>

[quote=“MisterFreez”]`NOM=`sed -e "s/\(.\):.*$/\1/g"`
VALEUR=`sed -e "s/^.*:\(.\)/\1/g"``  
Mais du coup tu peut pas travailler sur des flux.

Le problème c’est qu’avec ta technique même si un export par exemple fonction tu ne va récupérer que la dernière valeur (avec mon code c’est une liste que tu chope).[/quote]  
C’est la solution à laquelle je me suis résigné…

J’aurais bien aimé une solution plus propre (même s’il faut se passer de sed :’(), histoire que le jour où je ferais la même chose avec nomX:valeur1:valeur2:…:valeur100, je ne me retrouve pas avec 100 lignes et 100 appels à sed 😛

---

<div class="post-metadata">

**Author:** ![thialme](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/t/50afbb/32.png) [@thialme](https://www.debian-fr.org/u/thialme)\
**Post date:** [Février 20, 2016, 4:19 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098/5 "2016-02-20T16:19:31Z")

</div>

Il faudrait posté tout le problème, pour vraiment pouvoir aidé. C’est un peu comme dire que cela ne fonctionne pas mais sans fournir de message d’erreur. 🙂

---

<div class="post-metadata">

**Author:** ![Aeris1](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/b4bc9f/32.png) [@Aeris1](https://www.debian-fr.org/u/Aeris1)\
**Post date:** [Février 20, 2016, 4:19 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098/6 "2016-02-20T16:19:31Z")

</div>

Le problème a déjà été exposé plus haut 😃  
J’ai un fichier qui contient des valeurs, séparées par des :  
Et j’ai envie de récupérer chaque valeur dans une variable bash pour vérifier que le couple est autorisé.  
En gros:

`$cat list.txt
nom1:valeur1ok
nom2:valeur2pasok
nom3:valeur3ok
...`

[code]$cat getOK  
#!/bin/bash  
rm good.txt  
while read line  
do  
# La ligne qu’il me manque, pour affecter les valeurs trouvées dans des variables bash  
???

```
    echo $NAME $VALUE
    # test_config est un exécutable qui permet de savoir si le couple (NAME, VALUE) est valide ou non
    test_config $NAME $VALUE
    if [$? -eq 0]
    then
            echo $NAME:$VALUE >> good.txt
    fi

```

done \< list.txt[/code]

`$cat good.txt
$./getOk
nom1 valeur1ok
nom2 valeur2pasok
nom3 valeur3ok
$cat good.txt
nom1:valeur1ok
nom3:valeur3ok`

Voila le bidule en gros. En plus je m’attend à devoir complexifier le bordel en ayant besoin des variables dans un script plus complexe, donc un`test_config `echo "$line" | sed 's/blabla/\1 \2/'``n’est pas envisageable 😃

---

<div class="post-metadata">

**Author:** ![thialme](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/t/50afbb/32.png) [@thialme](https://www.debian-fr.org/u/thialme)\
**Post date:** [Février 20, 2016, 4:19 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098/7 "2016-02-20T16:19:32Z")

</div>

```auto
thialme@sid:~$ cat tmp 
chemin1:1
chemin2:2
chemin3:3
thialme@sid:~$ MYDATA=`awk -F : '{ print $1 " " $2 }' tmp`
thialme@sid:~$ for i in $MYDATA; do echo $i; done;
chemin1
1
chemin2
2
chemin3
3
```

---

<div class="post-metadata">

**Author:** ![Aeris1](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/b4bc9f/32.png) [@Aeris1](https://www.debian-fr.org/u/Aeris1)\
**Post date:** [Février 20, 2016, 4:19 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098/8 "2016-02-20T16:19:32Z")

</div>

Ouaip, on peut le voir comme ça.  
Le problème après, c’est de mettre ça dans des variables 😛  
Pour 2 ou 3 valeurs, ça passe à coup de if dans le for, pour 100 ou 200, on commence à pleurer 😛

Sinon, y’a pas de solution plus élégante, dans le style du list() en php?

---

<div class="post-metadata">

**Author:** ![thialme](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/t/50afbb/32.png) [@thialme](https://www.debian-fr.org/u/thialme)\
**Post date:** [Février 20, 2016, 4:19 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098/9 "2016-02-20T16:19:32Z")

</div>

Je vois mieux, ce que je n’avais pas compris au début 😊

Si tu veux vraiment faire un truc propre moi je le ferais en perl pour avoir quelque chose de facile à manipuler si des changements surviennent. C’est sympa à faire et puis il doit y avoir des fonctions toutes indiquées pour faire ce que tu recherches (mais je ne la connais pas 😆 )

---

<div class="post-metadata">

**Author:** ![swiip81](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/s/9de0a6/32.png) [@swiip81](https://www.debian-fr.org/u/swiip81)\
**Post date:** [Février 20, 2016, 4:19 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098/10 "2016-02-20T16:19:32Z")

</div>

Dans le même genre avec awk tu as

```auto
#!/bin/bash
awk -F : 'BEGIN { NAME [NR] = $1 ; VALUE [NR] = $2 }
END { for ( i = NR ; i >= 1 ; i-- )
      {
# test_config NAME [i] VALUE [i]
# if ( $? -eq 0 )
# then
          print NAME [i] ":" VALUE [i] # >> good.txt
# fi
      }
    }' list.txt
```

qui te reconstruit la liste

`18:12:59 florent@SrvLinux: ~/testtmmp$ cat list.txt 
nom1:valeur1
nom2:valeur2
nom3:valeur3
nom4:valeur4
nom5:valeur5
nom6:valeur6
18:14:05 florent@SrvLinux: ~/testtmmp$ ./leprog 
nom6:valeur6
nom5:valeur5
nom4:valeur4
nom3:valeur3
nom2:valeur2
nom1:valeur1`

Cf [shellunix.com/awk.html](http://www.shellunix.com/awk.html)

---

<div class="post-metadata">

**Author:** ![usinagaz](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/u/ecae2f/32.png) [@usinagaz](https://www.debian-fr.org/u/usinagaz)\
**Post date:** [Février 20, 2016, 4:20 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098/11 "2016-02-20T16:20:56Z")

</div>

[quote=“Aéris”]Bonjour à tous.  
J’ai un petit problème avec sed, et j’espère que quelqu’un ici pourra m’aiguiller vers une solution.

J’ai un fichier contenant une liste de valeurs, sous la forme:`nom1:valeur1
nom2:valeur2
...`[/quote]  
Je pense que tu te complique la vie, ce que tu veux faire, c’est que bash interpréte nom1:valeur1 comme étant nom1 = valeur1 ?  
Si c’est le cas, trés facile … 2 cas de figures :  
1/ ton fichier est formaté par un autre prog, et tu dois alors soit créer un fichier tmp contenant les mêmes lignes à la différence que les ‘:’ seront remplacés par ‘=’ =\> sed le fait trés bien !  
2/ tu formates toi-même le fichier de données, et dans ce cas, remplace le rendu nom1:valeur1 par nom1=valeur1

Maintenant, tes données variables sont accessibles par tous les shells,sous-shell, à conditions qu’ils aient sourcé le fichier de données :  
. /tmp.data ou source /tmp.data

n’est ce pas ??

---

<div class="post-metadata">

**Author:** ![Aeris1](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/b4bc9f/32.png) [@Aeris1](https://www.debian-fr.org/u/Aeris1)\
**Post date:** [Février 20, 2016, 4:20 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098/12 "2016-02-20T16:20:59Z")

</div>

C’est presque ça sans être ça 😃

En fait, chaque couple nom:valeur doit passer dans une moulinette.  
J’ai trouvé 2 solutions, mais sans être capable d’en appliquer une seule…

En partant de`nom1:valeur1
nom2:valeur2
...`\* soit je parvient à récupérer chaque nomXXX et chaque valeurXXX dans une variable pour chaque ligne`1ère itération: NOM=nom1, VALEUR=valeur1
2nde itération: NOM=nom2, VALEUR=valeur2
3ème itération: ...`et dans ce cas je traite le tout avec un while, en modifiant les valeurs à chaque passage

- soit je récupère un tableau associatif`ARRAY[1][1]=nom1, ARRAY[1][2]=valeur1
ARRAY[2][1]=nom2, ARRAY[2][2]=valeur2
...`que je génère au début du script et que je traite par la suite.

---

<div class="post-metadata">

**Author:** ![usinagaz](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/u/ecae2f/32.png) [@usinagaz](https://www.debian-fr.org/u/usinagaz)\
**Post date:** [Février 20, 2016, 4:21 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098/13 "2016-02-20T16:21:00Z")

</div>

je te suis pas là … soit plus explicite sur ce que tu veux faire, et donnes des exemples concrets, un extrait de code, et non des valeurs génériques style nom1 nom2 valeur1 valeur2 (extrait de fichier, extrait de script de traitement du fichier …)  
Attention, dans ton exemple, il ne s’agit pas d’un tableau associatif, mais d’un tableau à deux dimensions … ou tableau de tableaux.

---

<div class="post-metadata">

**Author:** ![Aeris1](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/b4bc9f/32.png) [@Aeris1](https://www.debian-fr.org/u/Aeris1)\
**Post date:** [Février 20, 2016, 4:21 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098/14 "2016-02-20T16:21:03Z")

</div>

bis repetita 😃  
[forum.debian-fr.org/viewtopic.php?p=90550#90550](http://forum.debian-fr.org/viewtopic.php?p=90550#90550)

Pour l’instant, j’ai résolu le problème avec un programme en c++ fait-main et des regexp.  
Mais cette question me taraude toujours 😛  
Comment récupérer dans une variable bash la sortie d’une regexp sed, à la manière d’un preg\_match ou preg\_match\_all php en gros…

[code]#cat \> test.php \<\< EOF

\<?php $data = "nom1:valeur1\nnom2:valeur2"; echo $data."\n\n"; preg\_match\_all("#^([^:]+):(.\*+)$#m", $data, $result, PREG\_SET\_ORDER); print\_r($result); ?\>

EOF  
#php test.php  
nom1:valeur1  
nom2:valeur2

Array  
(  
[0] =\> Array  
(  
[0] =\> nom1:valeur1  
[1] =\> nom1  
[2] =\> valeur1  
)

```
[1] => Array
    (
        [0] => nom2:valeur2
        [1] => nom2
        [2] => valeur2
    )

```

)[/code]ou[code]#cat \> test.php \<\< EOF\<?php  
$data = “nom1:valeur1\nnom2:valeur2”;  
echo $data."\n\n";  
$lines = split("\n", $data);  
print\_r($lines);  
foreach ( $lines as $l ) {  
preg\_match("#([^:]+):(.\*)#", $l, $result);  
print\_r($result);  
}  
?\>  
EOF  
#php test.php  
nom1:valeur1  
nom2:valeur2

Array  
(  
[0] =\> nom1:valeur1  
[1] =\> nom2:valeur2  
)  
Array  
(  
[0] =\> nom1:valeur1  
[1] =\> nom1  
[2] =\> valeur1  
)  
Array  
(  
[0] =\> nom2:valeur2  
[1] =\> nom2  
[2] =\> valeur2  
)[/code]

---

<div class="post-metadata">

**Author:** ![usinagaz](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/u/ecae2f/32.png) [@usinagaz](https://www.debian-fr.org/u/usinagaz)\
**Post date:** [Février 20, 2016, 4:21 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098/15 "2016-02-20T16:21:04Z")

</div>

`debian:/home/jcode# line=nom1:valeur1
debian:/home/jcode# echo $line
nom1:valeur1
debian:/home/jcode# nom=${line%:*}
debian:/home/jcode# echo $nom
nom1
debian:/home/jcode# valeur=${line#*:}
debian:/home/jcode# echo $valeur
valeur1
`😃😈

en d’autres termes … test\_config ${line%:_} ${line#_:}

---

<div class="post-metadata">

**Author:** ![Aeris1](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/b4bc9f/32.png) [@Aeris1](https://www.debian-fr.org/u/Aeris1)\
**Post date:** [Février 20, 2016, 4:21 UTC](https://www.debian-fr.org/t/sed-et-variable-bash/9098/16 "2016-02-20T16:21:04Z")

</div>

Oo  
oO

C’est quoi c’te syntaxe!!!  
(M’enfin si ça marche ^^)
