coquille
Le chargement d'une langue de niveau supérieur prend du temps.
Pour quelques lignes, le shell lui-même peut être une solution.
Nous pouvons utiliser la commande externe sort
et la commande tr
. L'une est assez efficace pour trier les lignes et l'autre est efficace pour convertir un délimiteur en nouvelles lignes:
#!/bin/bash
shsort(){
while IFS='' read -r line; do
echo "$line" | tr "$1" '\n' |
sort -n | paste -sd "$1" -
done <<<"$2"
}
shsort ' ' '10 50 23 42'
shsort '.' '10.1.200.42'
shsort ',' '1,100,330,42'
shsort '|' '400|500|404'
shsort ',' '3 b,2 x,45 f,*,8jk'
shsort '.' '10.128.33.6
128.17.71.3
44.32.63.1'
Ce besoin bash en raison de l'utilisation de <<<
seulement. S'il est remplacé par un here-doc, la solution est valable pour posix.
Ceci est en mesure de trier les champs avec des onglets, des espaces ou des caractères glob shell ( *
, ?
, [
). Pas de nouvelles lignes car chaque ligne est en cours de tri.
Changez <<<"$2"
pour <"$2"
traiter les noms de fichiers et appelez-le comme:
shsort '.' infile
Le délimiteur est le même pour tout le fichier. Si c'est une limitation, elle pourrait être améliorée.
Cependant, un fichier avec seulement 6000 lignes prend 15 secondes pour être traité. Vraiment, le shell n'est pas le meilleur outil pour traiter les fichiers.
Awk
Pour plus de quelques lignes (plus de quelques 10), il est préférable d'utiliser un vrai langage de programmation. Une solution awk pourrait être:
#!/bin/bash
awksort(){
gawk -v del="$1" '{
split($0, fields, del)
l=asort(fields)
for(i=1;i<=l;i++){
printf( "%s%s" , (i==0)?"":del , fields[i] )
}
printf "\n"
}' <"$2"
}
awksort '.' infile
Ce qui ne prend que 0,2 seconde pour le même fichier de 6000 lignes mentionné ci-dessus.
Comprenez que les <"$2"
fichiers for peuvent être modifiés <<<"$2"
pour les lignes dans les variables shell.
Perl
La solution la plus rapide est Perl.
#!/bin/bash
perlsort(){ perl -lp -e '$_=join("'"$1"'",sort {$a <=> $b} split(/['"$1"']/))' <<<"$2"; }
perlsort ' ' '10 50 23 42'
perlsort '.' '10.1.200.42'
perlsort ',' '1,100,330,42'
perlsort '|' '400|500|404'
perlsort ',' '3 b,2 x,45 f,*,8jk'
perlsort '.' '10.128.33.6
128.17.71.3
44.32.63.1'
Si vous voulez trier un changement de fichier <<<"$a"
simplement "$a"
et ajouter des -i
options à perl pour rendre l'édition de fichier "en place":
#!/bin/bash
perlsort(){ perl -lpi -e '$_=join("'"$1"'",sort {$a <=> $b} split(/['"$1"']/))' "$2"; }
perlsort '.' infile; exit