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).
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.
;-)
-- Olivier Miakinen
Le 08/09/2010 10:49, Lucas Levrel 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.
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.
;-)
-- Olivier Miakinen
Cyrille Lefevre
Le 07/09/2010 23:08, Michel Talon a écrit :
Je ne sais pas pourquoi il y a un blanc au début. Une solution avec l e awk de gnu (le awk standard n'a pas de fonction de tri), c'est nettemen t plus merdique qu'en perl:
(echo FADBEC;echo CACBAC) | awk ' function qsort(A, left, right, i, last) { #swap(A, left, last) if (left >= right) return swap(A, left, left+int((right-left+1)*rand())) last = left for (i = left+1; i <= right; i++) if (A[i] < A[left]) swap(A, ++last, i) swap(A, left, last) qsort(A, left, last-1) qsort(A, last+1, right) } function swap(A, i, j, t) { t = A[i]; A[i] = A[j]; A[j] = t } {gsub(/./,"& ");n=split($0,a);qsort(a,1,n);l="";for(i=1;i<=n;i++) l=l a[i];print l}'
Cordialement,
Cyrille Lefevre. -- mailto:Cyrille.Lefevre-news% supprimer "%nospam% et ".invalid" pour me repondre. remove "%nospam" and ".invalid" to answer me.
Le 07/09/2010 23:08, Michel Talon a écrit :
Je ne sais pas pourquoi il y a un blanc au début. Une solution avec l e
awk de gnu (le awk standard n'a pas de fonction de tri), c'est nettemen t
plus merdique qu'en perl:
(echo FADBEC;echo CACBAC) | awk '
function qsort(A, left, right, i, last) {
#swap(A, left, last)
if (left >= right)
return
swap(A, left, left+int((right-left+1)*rand()))
last = left
for (i = left+1; i <= right; i++)
if (A[i] < A[left])
swap(A, ++last, i)
swap(A, left, last)
qsort(A, left, last-1)
qsort(A, last+1, right)
}
function swap(A, i, j, t) {
t = A[i]; A[i] = A[j]; A[j] = t
}
{gsub(/./,"& ");n=split($0,a);qsort(a,1,n);l="";for(i=1;i<=n;i++) l=l
a[i];print l}'
Cordialement,
Cyrille Lefevre.
--
mailto:Cyrille.Lefevre-news%nospam@laposte.net.invalid
supprimer "%nospam% et ".invalid" pour me repondre.
remove "%nospam" and ".invalid" to answer me.
Je ne sais pas pourquoi il y a un blanc au début. Une solution avec l e awk de gnu (le awk standard n'a pas de fonction de tri), c'est nettemen t plus merdique qu'en perl:
(echo FADBEC;echo CACBAC) | awk ' function qsort(A, left, right, i, last) { #swap(A, left, last) if (left >= right) return swap(A, left, left+int((right-left+1)*rand())) last = left for (i = left+1; i <= right; i++) if (A[i] < A[left]) swap(A, ++last, i) swap(A, left, last) qsort(A, left, last-1) qsort(A, last+1, right) } function swap(A, i, j, t) { t = A[i]; A[i] = A[j]; A[j] = t } {gsub(/./,"& ");n=split($0,a);qsort(a,1,n);l="";for(i=1;i<=n;i++) l=l a[i];print l}'
Cordialement,
Cyrille Lefevre. -- mailto:Cyrille.Lefevre-news% supprimer "%nospam% et ".invalid" pour me repondre. remove "%nospam" and ".invalid" to answer me.
talon
Cyrille Lefevre <cyrille.lefevre-news% wrote:
Le 07/09/2010 23:08, Michel Talon a écrit :
> 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
C'est essentiellement le même ... Tu as supprimé le begin et mis l'initialisation de l et du caractère de split ailleurs, et j'avais rajouté un mangeur de blancs (gsub()) pour imiter le résultat du script perl. Une scorie inutile chez moi, l'introduction de A et B, car j'avais une sortie fausse, en utilisant for(i in a) l=l a[i] ce qui ne marche pas. Il faut utiliser explicitement l'indice. Ensuite j'ai oublié la scorie.
Bref, le script awk a l'air bien plus compliqué que le script perl, mais au moins il n'y a pas toutes ces choses implicites cachées dans le script perl, dont j'ai personnellement horreur. Tout est parfaitement explicite. Celà étant s'il faut en plus fabriquer une fonction de tri, ça devient prohibitif. Incidemment, il existe un machin "runawk" qui possède une collection de fonctions awk, et en particulier une fonction de tri, ce qui augmente l'utilité de awk. http://sourceforge.net/projects/runawk/files/ voir runawk-1.0.0. Utiliser gawk améliore déjà grandement le awk standard nawk, ne serait-ce que via des expressions régulières plus puissantes, et quelques fonctions utiles comme le tri.
> 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
C'est essentiellement le même ...
Tu as supprimé le begin et mis l'initialisation de l et du caractère de
split ailleurs, et j'avais rajouté un mangeur de blancs (gsub()) pour
imiter le résultat du script perl. Une scorie inutile chez moi,
l'introduction de A et B, car j'avais une sortie fausse, en utilisant
for(i in a) l=l a[i] ce qui ne marche pas. Il faut utiliser
explicitement l'indice. Ensuite j'ai oublié la scorie.
Bref, le script awk a l'air bien plus compliqué que le script perl, mais
au moins il n'y a pas toutes ces choses implicites cachées dans le
script perl, dont j'ai personnellement horreur. Tout est parfaitement
explicite. Celà étant s'il faut en plus fabriquer une fonction de tri,
ça devient prohibitif. Incidemment, il existe un machin "runawk" qui
possède une collection de fonctions awk, et en particulier une fonction
de tri, ce qui augmente l'utilité de awk.
http://sourceforge.net/projects/runawk/files/
voir runawk-1.0.0.
Utiliser gawk améliore déjà grandement le awk standard nawk, ne
serait-ce que via des expressions régulières plus puissantes, et
quelques fonctions utiles comme le tri.
> 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
C'est essentiellement le même ... Tu as supprimé le begin et mis l'initialisation de l et du caractère de split ailleurs, et j'avais rajouté un mangeur de blancs (gsub()) pour imiter le résultat du script perl. Une scorie inutile chez moi, l'introduction de A et B, car j'avais une sortie fausse, en utilisant for(i in a) l=l a[i] ce qui ne marche pas. Il faut utiliser explicitement l'indice. Ensuite j'ai oublié la scorie.
Bref, le script awk a l'air bien plus compliqué que le script perl, mais au moins il n'y a pas toutes ces choses implicites cachées dans le script perl, dont j'ai personnellement horreur. Tout est parfaitement explicite. Celà étant s'il faut en plus fabriquer une fonction de tri, ça devient prohibitif. Incidemment, il existe un machin "runawk" qui possède une collection de fonctions awk, et en particulier une fonction de tri, ce qui augmente l'utilité de awk. http://sourceforge.net/projects/runawk/files/ voir runawk-1.0.0. Utiliser gawk améliore déjà grandement le awk standard nawk, ne serait-ce que via des expressions régulières plus puissantes, et quelques fonctions utiles comme le tri.
--
Michel TALON
Alain Ketterlin
Olivier Miakinen <om+ writes:
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.
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.
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.