Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

substitution de commande et variable

16 réponses
Avatar
Christophe PEREZ
Bonjour,

Je ne suis pas sûr d'avoir mis exactement le bon titre.

En bash, je peux faire :
${VARIABLEquelque_chose}
Mais si par exemple VARIABLE égale le résultat d'une commande genre :
VARIABLE="$(grep machin fichier)"

Est-il possible, par un syntaxe bien trouvée (mais pas par moi) de le
faire en une commande sans passer par cette VARIABLE intermédiaire bien
souvent inutile ?
Genre :
VARIABLE=${ (grep machin fichier)/machin/truc}
J'ai essayé des multitudes de choses possibles, mais sans jamais y
arriver.

Tiens, tant que j'y suis à parler de ma lecture de man bash, j'ai 2
questions :
1) Que veut donc dire :
${paramètre:début:longueur}
[...]Si le début est négatif,
sa valeur est considérée à partir de la fin du contenu du
paramètre.
$ A="bonjour"
$ echo "${A:-1:4}"
bonjour

?

2) Puisque les tableaux dans bash ne peuvent avoir qu'une dimension,
comment simuler une multi-dimension ?
J'ai bien pensé à faire un :
ARTICLE1=("param 1" "param2" ...)
ARTICLE2=("param 1" "param2" ...)
Puis traiter le ARTICLE$I, mais ça me pose quelques problèmes de forme,
je ne connais pas le nombre d'articles, et si je m'arrête au premier
vide, cela veut dire que tous les numéros doivent se suivre sans qu'il y
ait de trous.
Enfin bref, comment faites-vous ?

En bash, hein, en bash ! Car tout ça, c'est plus par curiosité que par
besoin.

--
Christophe PEREZ
Écrivez moi sans _faute !

10 réponses

1 2
Avatar
Stephane Chazelas
2004-01-26, 18:53(-04), Christophe PEREZ:
[...]
En bash, je peux faire :
${VARIABLEquelque_chose}
Mais si par exemple VARIABLE égale le résultat d'une commande genre :
VARIABLE="$(grep machin fichier)"

Est-il possible, par un syntaxe bien trouvée (mais pas par moi) de le
faire en une commande sans passer par cette VARIABLE intermédiaire bien
souvent inutile ?
Genre :
VARIABLE=${ (grep machin fichier)/machin/truc}
[...]


Pas avec bash. Il n'est pas évident de combiner ces trucs avec
bash, dès que tu fais des trucs un peu inattendus, tu rentres
vite dans des bugs, c'est pire avec ksh93. Avec zsh, tu peux
tout combiner dans tous les sens, mais c'est souvent plus
lisible de passer par des variables intermédiaires.

Cela dit:

VARIABLE=$(sed -n 's/machin/truc/p' < fichier)

ça marche aussi bien et c'est portable.
Quand on utilise bash, c'est plus pour avoir un shell POSIX
conformant ; moi, j'éviterais d'utiliser les trucs non standard
(${var/a/b} en fait partie).

[...]
1) Que veut donc dire :
${paramètre:début:longueur}
[...]Si le début est négatif,
sa valeur est considérée à partir de la fin du contenu du
paramètre.
$ A="bonjour"
$ echo "${A:-1:4}"
bonjour
[...]


Encore une connerie de ksh93 pompée par bash, et à ne pas
utiliser (encore qu'il se pourrait bien que les index négatifs
aient été introduits dans bash avant ksh93).

${var:offset:length} a été rajouté sans réaliser que ça rentrait
en conflit avec ${var:-default}. Tu dois utiliser ${A: -1:4}
(avec l'espace) ou alors ça sera pris comme "renvoyer 1:4 si A
est vide ou indéfinie".

Attention, avec les tableaux, les chiffres ne correspondent pas
aux index, mais au numéro d'ordre dans la liste.

Avec zsh: $A[debut,fin]

Les tableaux de zsh sont vraiment des tableaux, pas des "hash"
comme dans bash/ksh93 (zsh a aussi des "hash" mais qui ne se
limitent pas à des indices sous forme de nombre entier)


[...]
2) Puisque les tableaux dans bash ne peuvent avoir qu'une dimension,
comment simuler une multi-dimension ?


Comme avec le Bourne shell, mais, déjà que c'est une erreur de
continuer à utiliser un shell quand on a besoin de tableaux,
avec un tableau à deux dimensions...

indice1=4 indice2 value=whatever
eval "array_${indice1}_${indice2}=$value"
#puis
value=$array_4_12

Mais, en shell, il y a toutes les chances que tu t'y prennes de
la mauvaise façon si tu envisages d'utiliser des tableaux.

--
Stéphane ["Stephane.Chazelas" arobase "free.fr"]

Avatar
Bernard Déléchamp
Christophe PEREZ wrote:
Bonjour,


Idem et bonne année, il est encore temps ;-)

[...]

J'ai essayé des multitudes de choses possibles, mais sans jamais y
arriver.


Sais pas, je ne pense pas, mais ça pourrait vite devenir imbitable.

Tiens, tant que j'y suis à parler de ma lecture de man bash, j'ai 2
questions :
1) Que veut donc dire :
${paramètre:début:longueur}
[...]Si le début est négatif,
sa valeur est considérée à partir de la fin du contenu du
paramètre.
$ A="bonjour"
$ echo "${A:-1:4}"
bonjour


[ bernard]$ A="bonjour"
[ bernard]$ echo ${A: -4:1}
j
[ bernard]$ echo ${A: -4}
jour

Note l'espace devant le tiret. Une lecture du man de bash te donnera une
explication ;-) (chercher ${parametre:-mot})

Même résultat :

[ bernard]$ echo ${A:101-105}
jour

?

2) Puisque les tableaux dans bash ne peuvent avoir qu'une dimension,
comment simuler une multi-dimension ?


sais pas :-(

--
Un groupe de loups, c'est une horde. Un groupe de vaches, c'est un
troupeau. Un groupe d'hommes, c'est souvent une bande de cons.
Philippe Geluck

Avatar
Pascal Bourguignon
Christophe PEREZ writes:

Bonjour,

Je ne suis pas sûr d'avoir mis exactement le bon titre.

En bash, je peux faire :
${VARIABLEquelque_chose}
Mais si par exemple VARIABLE égale le résultat d'une commande genre :
VARIABLE="$(grep machin fichier)"

Est-il possible, par un syntaxe bien trouvée (mais pas par moi) de le
faire en une commande sans passer par cette VARIABLE intermédiaire bien
souvent inutile ?
Genre :
VARIABLE=${ (grep machin fichier)/machin/truc}
J'ai essayé des multitudes de choses possibles, mais sans jamais y
arriver.


De faire QUOI ? Exprime toi !

Allez, au hasard :

eval $(grep machin fichier)


Tiens, tant que j'y suis à parler de ma lecture de man bash, j'ai 2
questions :
1) Que veut donc dire :
${paramètre:début:longueur}
[...]Si le début est négatif,
sa valeur est considérée à partir de la fin du contenu du
paramètre.
$ A="bonjour"
$ echo "${A:-1:4}"
bonjour
?


Bash n'est pas trés clair sur les sous-chaines. :- signifie autre
chose, alors il faut mettre des parenthèses:

$ a=bonjour
$ echo ${a:2:3}
njo
$ echo ${a:(-4):3}
jou


2) Puisque les tableaux dans bash ne peuvent avoir qu'une dimension,
comment simuler une multi-dimension ?
J'ai bien pensé à faire un :
ARTICLE1=("param 1" "param2" ...)
ARTICLE2=("param 1" "param2" ...)
Puis traiter le ARTICLE$I, mais ça me pose quelques problèmes de forme,
je ne connais pas le nombre d'articles, et si je m'arrête au premier
vide, cela veut dire que tous les numéros doivent se suivre sans qu'il y
ait de trous.
Enfin bref, comment faites-vous ?


Moi, je laisse tomber bash et je programme mes scripts en clisp.

Sinon :

dim2 () {
eval "${1}_dim1=$2"
eval "${1}_dim2=$3"
}

aref2 () {
local dim2=${1}_dim2
eval "echo ${${1}[$(( ( $2 * ${!dim2} ) + $3 ))]}"
}

aset2 () {
local dim2=${1}_dim2
eval "${1}[$(( ( $2 * ${!dim2} ) + $3 ))]=$4"
}

dim2 tab 3 5
for i in 0 1 2 ; do for j in 0 1 2 3 4 ; do aset2 tab $i $j $i-$j ; done ; done
echo ${tab[@]}
for i in 0 1 2 ; do echo '' ;
for j in 0 1 2 3 4 ; do echo -n " $(aref2 tab $i $j) " ; done ;
done ; echo ''

donne :

0-0 0-1 0-2 0-3 0-4 1-0 1-1 1-2 1-3 1-4 2-0 2-1 2-2 2-3 2-4
0-0 0-1 0-2 0-3 0-4
1-0 1-1 1-2 1-3 1-4
2-0 2-1 2-2 2-3 2-4

En bash, hein, en bash ! Car tout ça, c'est plus par curiosité que par
besoin.


C'est même plus de la curiosité, c'est carément du masochisme!


--
__Pascal_Bourguignon__ http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/

Avatar
Stephane Chazelas
2004-01-27, 12:54(+01), Pascal Bourguignon:
[...]
Bash n'est pas trés clair sur les sous-chaines. :- signifie autre
chose, alors il faut mettre des parenthèses:

$ a=bonjour
$ echo ${a:2:3}
njo
$ echo ${a:(-4):3}
jou
[...]


Well, préférer le ${a: -4:3}
$ a=bonjour
$ echo ${a:(-4):3}
ksh93: (-4):3: arithmetic syntax error

(quand je disais que ksh93 était pas mal buggué...)

--
Stéphane ["Stephane.Chazelas" arobase "free.fr"]

Avatar
Stephane Chazelas
2004-01-27, 13:33(+01), Stephane Chazelas:
[...]
$ echo ${a:(-4):3}
jou
[...]


Well, préférer le ${a: -4:3}
$ a=bonjour
$ echo ${a:(-4):3}
ksh93: (-4):3: arithmetic syntax error
[...]


C'qu'on se marre:

~$ ksh93 -c 'a34567; echo $((${a:(-3):4}))'
567

~$ ksh93 -c 'a34567; echo ${a:"-3":4}'
567

~$ ksh93 -c 'a34567; echo $((${a:"-3":4}))'
ksh93: line 1: "-3":4: arithmetic syntax error

~$ ksh93 -c 'a34567; IFS="()"; echo ${a:(-3):4}'
ksh93: line 1: :4: arithmetic syntax error

~$ ksh93 -c 'a34567; echo ${a: -3 : 4 }'
zsh: segmentation fault ksh93 -c 'a34567; echo ${a: -3 : 4 }'

~$ ksh93 -c 'a34567; echo ${a:0:1}'
1

~$ ksh93 -c 'a34567 IFS=:; echo ${a:0:1}'
0 234567

~$ bash -c 'a34567; echo ${a:"-3":4}'
bash: line 1: a: "-3": syntax error: operand expected (error token is ""-3"")

Quand on cherche trop profond, la logique, elle s'envolle.

--
Stéphane ["Stephane.Chazelas" arobase "free.fr"]


Avatar
Christophe PEREZ
Le Tue, 27 Jan 2004 10:52:54 +0100, Stephane Chazelas a écrit:

VARIABLE=${ (grep machin fichier)/machin/truc}


Pas avec bash.


Ben voilà ! Je me disais bien... :-)

[...]
Cela dit:

VARIABLE=$(sed -n 's/machin/truc/p' < fichier)


C'est ce que je fais (dans le genre) pour l'instant, mais je pensais qu'il
pouvait être judicieux de rester dans des fonctions bash plutôt que de
faire appel à des commandes "externes".

moi, j'éviterais d'utiliser les trucs non standard
(${var/a/b} en fait partie).


Arf'...

Encore une connerie de ksh93 pompée par bash, et à ne pas
utiliser (encore qu'il se pourrait bien que les index négatifs
aient été introduits dans bash avant ksh93).


Et paf... pour une fois que je lis un man (joke)

Tu dois utiliser ${A: -1:4}


J'avais bien essayé des trucs du genre (en mettant des parenthèses aux
nombres) mais :
$ A="bonjour"
$ echo ${A: -1:4}
r

Moi, je veux les 4 derniers caractères d'une chaîne.

Comme avec le Bourne shell, mais, déjà que c'est une erreur de
continuer à utiliser un shell quand on a besoin de tableaux,
avec un tableau à deux dimensions...


Arf'...
En fait, j'ai dans mon script, une configuration de périphériques, où
chaque périphérique a ses 3 arguments chaîne.
Ex :
Périphérique 1 = "a17/6/100" "App.Photo" "/usr/share/icons/icone1.png"
(c'est pour la gestion des périphériques usb)
Je pourrais mettre ça dans un fichier de configuration, mais en supposant
que je ne le souhaite pas ?
Pour l'instant, je met tout dans une même chaîne, séparé par des
tabulations, et je scinde ça par des "cut" pour récupérer chaque
paramètre.

[...]
value=$array_4_12


Certes...

Mais, en shell, il y a toutes les chances que tu t'y prennes de
la mauvaise façon si tu envisages d'utiliser des tableaux.


C'est pour ça que je me suis finalement décidé ci-dessus à exposer
plus précisément ma problématique ;-)

Merci pour toutes ces explications.

--
Christophe PEREZ
Écrivez moi sans _faute !


Avatar
Christophe PEREZ
Le Tue, 27 Jan 2004 10:58:06 +0100, Bernard Déléchamp a écrit:

Idem et bonne année, il est encore temps ;-)


Ah ouais, mince!
Bonne année à toi (et à tous!:-) ).

Sais pas, je ne pense pas, mais ça pourrait vite devenir imbitable.


Ça ne serait pas le premier exemple ;-)

[ bernard]$ echo ${A: -4}
jour


Argh...

Note l'espace devant le tiret. Une lecture du man de bash te donnera une
explication ;-) (chercher ${parametre:-mot})


J'y passe mon temps dans ce man, seul pb, c'est que je n'y comprends pas
grand chose ;-)


Merci.

--
Christophe PEREZ
Écrivez moi sans _faute !

Avatar
Christophe PEREZ
Le Tue, 27 Jan 2004 12:54:34 +0100, Pascal Bourguignon a écrit:

De faire QUOI ? Exprime toi !


C'est ce que j'ai tenté d'expliquer. Heureusement, d'autres ont compris ;-)

Allez, au hasard :

eval $(grep machin fichier)


Le hasard fait souvent mal les choses ;-)

Bash n'est pas trés clair sur les sous-chaines.


Bash, je ne sais pas, mais man bash, c'est certain :-)

dim2 tab 3 5
[...]


Wahou ! Je garde tout ça dans un coin et j'étudie à tête très reposée.
Merci.

C'est même plus de la curiosité, c'est carément du masochisme!


Je suis un peu comme ça, oui :-)

--
Christophe PEREZ
Écrivez moi sans _faute !

Avatar
Stephane Chazelas
2004-01-28, 13:34(-04), Christophe PEREZ:
[...]
VARIABLE=$(sed -n 's/machin/truc/p' < fichier)


C'est ce que je fais (dans le genre) pour l'instant, mais je pensais qu'il
pouvait être judicieux de rester dans des fonctions bash plutôt que de
faire appel à des commandes "externes".


Alors, c'est que tu prends un shell pour ce qu'il n'est pas: un
langage de programmation.

J'avais bien essayé des trucs du genre (en mettant des parenthèses aux
nombres) mais :
$ A="bonjour"
$ echo ${A: -1:4}
r

Moi, je veux les 4 derniers caractères d'une chaîne.


printf '%sn' "${A: -4}"

[...]
C'est pour ça que je me suis finalement décidé ci-dessus à exposer
plus précisément ma problématique ;-)


Utilise awk ou perl, si tu veux depuis un script shell. Même
Lisp, si tu veux, allez ;).

--
Stéphane ["Stephane.Chazelas" arobase "free.fr"]


Avatar
Stephane Chazelas
2004-01-28, 13:44(-04), Christophe PEREZ:
[...]
C'est même plus de la curiosité, c'est carément du masochisme!


Je suis un peu comme ça, oui :-)
[...]


Du masochisme mal placé. Les vrais masochistes écrivent en Lisp.

--
Stéphane ["Stephane.Chazelas" arobase "free.fr"]


1 2