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

Résolu/Fermé
toutmaispasaix - 27 mars 2009 à 11:07
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 - 27 mars 2009 à 17:48
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,
A voir également:

3 réponses

jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
27 mars 2009 à 11:13
Salut,

Une solution avec "sed" :
$ echo "unechainedecaractères" | sed -n 's/.\{3\}\(.\).\(.\).*/\1 \2/p'
c a
;-))
1
toutmaispasaix
27 mars 2009 à 12:34
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
27 mars 2009 à 12:57
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 samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 836 > toutmaispasaix
27 mars 2009 à 13:04
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 samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022
27 mars 2009 à 13:16
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 jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895 > fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022
27 mars 2009 à 13:17
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 samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 836
27 mars 2009 à 11:45
Salut,
Tu peux utiliser python aussi
a="unechainedecaractères"
print a[3], a[5]
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
27 mars 2009 à 11:48
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 jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
27 mars 2009 à 17:48
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