Shell : Extraire des caractères séparés

Résolu
toutmaispasaix -  
lami20j Messages postés 21331 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   -
Bonjour,

J'aimerais extraire en shell des caractères d'une chaîne à une position bien précise et si possible ne pas utiliser de fonctionnalité propre à bash ou autre mais plutôt une technique portable sur différents OS.
Je voudrais toujours récupérer le 4eme et le 6eme caractère d'une chaine de 10 caractères et ce de manière élégante. J'arrive à le faire mais en plusieurs fois et je suis persuadé qu'il y a un moyen simple de le faire.

Je vous remercie par avance.

Cordialement,

3 réponses

jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 896
 
Salut,

Une solution avec "sed" :
$ echo "unechainedecaractères" | sed -n 's/.\{3\}\(.\).\(.\).*/\1 \2/p'
c a
;-))
1
toutmaispasaix
 
Merci jipicy,

J'ai mis bien plus de temps à comprendre ta réponse que tu n'en a mis à l'écrire !
Enfin et encore je sais la réutiliser pour ce que je veux en faire mais je ne l'ai pas totalement compris!

Si je décompose ta commande sed -n 's/.\{3\}\(.\).\(.\).*/\1 \2/p'

.\{3\} permet d'obtenir le 3eme caractère (donc départ à 0) et définition de \1
\(.\) permet de sauter un caractère quel qu'il soit
. pour représenter le 6 eme char que je peux ainsi récupérer avec le \2
\(.\).* la je comprend pas trop si ce n'est la définition de la fin avec *
0
toutmaispasaix > toutmaispasaix
 
Ah non je crois que j'ai dit n'importe quoi, si je reprend :

.\{3\} permet de sauter les 3 premier caractères
\(.\) positionne la valeur pour \1
. passe un caractère
\(.\) positionne le \2

.* la je ne comprend toujours pas pourquoi * tout seul ne suffirait pas
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846 > toutmaispasaix
 
Salut,
Oui cette version de ton explication est correcte.
Le .*, c'est pour matcher avec tous les caractères suivants.
L'étoile tout seul n'a aucun sens, elle est là pour donner la répétition du motif précédent (ici le point : n'importe quelle caractère).
Mais pourquoi ne pas utiliser python ? C'est beaucoup plus clair quand même ^^.
0
toutmaispasaix > fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention  
 
Merci fiddy, je comprend maintenant toute la ligne!
De nouveau merci à jipicy pour la solution.

Pour python pas possible, je dois modifier des scripts existants en shell et les gens qui auront à le maintenir ensuite ne veulent que du shell.
0
jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 896 > fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention  
 
Mais pourquoi ne pas utiliser python ? C'est beaucoup plus clair quand même ^^.
Tout a fait Thi... oups fiddy ;-))

Mais c'est moins joli à l'œil ;-DD

PS. Merci pour le complément d'info sur sed pour notre ami toutmaispasaix...
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
Salut,
Tu peux utiliser python aussi
a="unechainedecaractères"
print a[3], a[5]
0
jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 896
 
C'est plus simple et sûrement plus portable ;-))

PS. Bon on attend lami20j avec Perl et dubcek avec awk ;-))
0
lami20j Messages postés 21331 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 570
 
Salut,

Juste pour s'amuser ;-) vu que des solutions ont été déjà données

$ perl -e '($x,$y)=unpack("x3 A1 x1 A1","unechainedecaractères");print "$x et $y\n"'
c et a
$ perl -e '($x,$y)=(split //,"unechainedecaractères")[3,5];print "$x et $y\n"'
c et a
$ perl -e '($x,$y)="unechainedecaractères"=~/.{3}(.).(.)/;print "$x et $y\n"'
c et a
$ perl -e '($x,$y)=("unechainedecaractères"=~/(.)/g)[3,5];print "$x et $y\n"'
c et a
$ perl -e '$h{++$i}=$_ for split //,"unechainedecaractères";print "$h{4} et $h{6}\n"'
c et a
$ perl -e '($x,$y)=(grep {//} "unechainedecaractères"=~/(.)/g)[3,5];print "$x et $y\n"'
c et a



0