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

Script de tri de caracteres

15 réponses
Avatar
Olivier Miakinen
Bonjour,

Je cherche à faire un tri de caractères, c'est-à-dire que par exemple la
chaîne FADBEC donnerait ABCDEF, mais aussi que la chaîne CACBAC
donnerait AABCCC.

Savez-vous s'il existe déjà une commande Unix me permettant de le faire,
ou bien auriez-vous une idée pour la construire simplement à partir des
outils standards (sed, awk, perl, etc.) ?

Pour info, tous les caractères sont en ASCII 7 bits, et un tri sur la
valeur des octets conviendrait parfaitement (pas besoin de faire un
traitement particulier sur la distinction majuscules/minuscules par
exemple).

Cordialement,
--
Olivier Miakinen

10 réponses

1 2
Avatar
Nicolas Richard
Le 07/09/10 15:41, Olivier Miakinen a écrit :
Savez-vous s'il existe déjà une commande Unix me permettant de le faire,
ou bien auriez-vous une idée pour la construire simplement à partir des
outils standards (sed, awk, perl, etc.) ?



Je propose la mauvaise solution suivante :
echo -n poueto | perl -e "print sort split('',<>)"

Pour info, tous les caractères sont en ASCII 7 bits,



Cela devrait marcher pour cette classe de caractères, mais ça peut péter
à tout instant : je ne sais pas comment, mais c'est sûrement lié à
l'encodage (essaye avec un accent... chez moi ça casse)

Good luck

N.
Avatar
Olivier Miakinen
Le 07/09/2010 16:34, Nicolas Richard a écrit :

Je propose la mauvaise



;-)

solution suivante :
echo -n poueto | perl -e "print sort split('',<>)"



Ça fonctionne sur un mot, oui. Je vais essayer de comprendre comment ça
marche (moi qui ne connais toujours pas le perl) pour l'adapter à des
fichiers de plusieurs lignes.

Pour info, tous les caractères sont en ASCII 7 bits,



Cela devrait marcher pour cette classe de caractères, mais ça peut péter
à tout instant : je ne sais pas comment, mais c'est sûrement lié à
l'encodage (essaye avec un accent... chez moi ça casse)



Probablement parce que tu as un encodage multibyte, très certainement
UTF-8. Si le tri se fait sur les octets au lieu des caractères, c'est
normal que ça casse.

Heureusement pour moi je ne suis pas dans ce cas.

Merci !
Avatar
xavier
Olivier Miakinen <om+ wrote:

s/n$//;



Pour faire ça, il y a une instruction : chomp()

--
XAv
In your pomp and all your glory you're a poorer man than me,
as you lick the boots of death born out of fear.
(Jethro Tull)
Avatar
Nicolas George
Matthieu M , dans le message
, a
écrit :
perl -ne 'chomp; print sort split(//); print "n"'



perl -ne 'chomp; print sort split(//), "n"'
Avatar
Paul Gaborit
À (at) 07 Sep 2010 17:30:44 GMT,
Nicolas George <nicolas$ écrivait (wrote):

Matthieu M , dans le message
, a
écrit :
perl -ne 'chomp; print sort split(//); print "n"'



perl -ne 'chomp; print sort split(//), "n"'



perl -lane 'print sort split //'

--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>
Avatar
Emmanuel Florac
Le Tue, 07 Sep 2010 16:46:42 +0200, Olivier Miakinen a écrit:


Ça fonctionne sur un mot, oui. Je vais essayer de comprendre comment ça
marche (moi qui ne connais toujours pas le perl) pour l'adapter à des
fichiers de plusieurs lignes.



Suffit d'appeler avec perl -n -e :)


--
L'esprit qu'on veut avoir gâte celui qu'on a.
Jean-Baptiste Louis Grisset.
Avatar
Olivier Miakinen
Le 07/09/2010 19:49, Paul Gaborit répondait à Nicolas George :

perl -ne 'chomp; print sort split(//), "n"'





Ça ne fait pas ce que l'on veut, mais il suffit de déplacer une
parenthèse pour que ça marche :

perl -ne 'chomp; print sort(split //), "n"'

perl -lane 'print sort split //'



Adopté. Merci aussi à Matthieu et Emmanuel pour l'option -n.

--
Olivier Miakinen
Avatar
talon
Nicolas George <nicolas$ wrote:
Matthieu M , dans le message
, a
écrit :
> perl -ne 'chomp; print sort split(//); print "n"'

perl -ne 'chomp; print sort split(//), "n"'



Tu es bien sûr?

rose% echo "toto abracadabra"|perl -ne 'chomp; print sort split(//),
"n"'

aaaaabbcdoorrttrose%


rose% echo "toto abracadabra"|perl -ne 'chomp; print sort
split(//);print "n"'
aaaaabbcdoorrtt
rose%

Je ne sais pas pourquoi il y a un blanc au début. Une solution avec le
awk de gnu (le awk standard n'a pas de fonction de tri), c'est nettement
plus merdique qu'en perl:

rose% echo "toto abracadabra"|awk 'BEGIN {FS="";line=""}{gsub("
*","");split($0,B);lon=asort(B,A);for (j=1;j<=lon;j++) line=line
A[j];print line}'
aaaaabbcdoorrtt

(attention, toute la commande sur une seule ligne).

--

Michel TALON
Avatar
Olivier Miakinen
Le 07/09/2010 23:08, Michel Talon à Nicolas George :

perl -ne 'chomp; print sort split(//), "n"'



Tu es bien sûr?

rose% echo "toto abracadabra"|perl -ne 'chomp; print sort split(//),
"n"'

aaaaabbcdoorrttrose%



C'est parce que le "n" se retrouve en paramètre du sort et non du print
(comme avant de le virer par chomp). Il est alors logiquement trié au
début, avant les lettres.

Déplacer une parenthèse suffit à corriger le problème.

rose% echo "toto abracadabra"|perl -ne 'chomp; print sort
split(//);print "n"'
aaaaabbcdoorrtt
rose%

Je ne sais pas pourquoi il y a un blanc au début.



C'est le blanc qui est entre « toto » et « abracadabra ». Rien que de
très normal là encore.

Une solution avec le
awk de gnu (le awk standard n'a pas de fonction de tri), c'est nettement
plus merdique qu'en perl:

rose% echo "toto abracadabra"|awk 'BEGIN {FS="";line=""}{gsub("*","");split($0,B);lon=asort(B,A);for (j=1;j<=lon;j++) line=line A[j];print line}'
aaaaabbcdoorrtt



Ouf ! Oui, je reconnais la supériorité de perl ici. ;-)

--
Olivier Miakinen
Avatar
Lucas Levrel
Le 7 septembre 2010, Olivier Miakinen a écrit :

Mais bon, je suis de plus en plus hors sujet. À moins qu'on ne me
signale une commande Unix qui remplace le script Perl,



Avec ton shell, tu crées un tableau de 128 entiers, tu comptes les
occurences des caractères, puis tu en affiches autant que nécessaire...
complexité linéaire.
--
LL
1 2