Sed et variable bash

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é unsed 's/\(.*\):\(.*\)/NOM=\1 VALEUR=\2/p' | shmais unecho $NOM $VALEURme 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?

Quelque chose comme cela :

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.

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=“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 :stuck_out_tongue:

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. :slightly_smiling:

Le problème a déjà été exposé plus haut :smiley:
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 untest_config `echo "$line" | sed 's/blabla/\1 \2/'`n’est pas envisageable :smiley:

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

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

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

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

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 :laughing: )

Dans le même genre avec awk tu as

#!/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

[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 ??

C’est presque ça sans être ça :smiley:

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 denom1:valeur1 nom2:valeur2 ...* soit je parvient à récupérer chaque nomXXX et chaque valeurXXX dans une variable pour chaque ligne1è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 associatifARRAY[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.

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.

bis repetita :smiley:
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 :stuck_out_tongue:
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]

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 :smiley: :smiling_imp:

en d’autres termes … test_config ${line%:} ${line#:}

Oo
oO

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