Cáscara
Cargar un idioma de nivel superior lleva tiempo.
Para algunas líneas, el shell en sí mismo puede ser una solución.
Podemos usar el comando externo sort
y el comando tr
. Uno es bastante eficiente en la clasificación de líneas y el otro es efectivo para convertir un delimitador en líneas nuevas:
#!/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'
Esto necesita bash debido al uso de <<<
solo. Si eso se reemplaza con un documento aquí, la solución es válida para posix.
Este es capaz de ordenar campos con tabulaciones, espacios o caracteres shell glob ( *
, ?
, [
). No nuevas líneas porque cada línea se está ordenando.
Cambie <<<"$2"
a <"$2"
para procesar nombres de archivos y llámelo como:
shsort '.' infile
El delimitador es el mismo para todo el archivo. Si eso es una limitación, podría mejorarse.
Sin embargo, un archivo con solo 6000 líneas tarda 15 segundos en procesarse. En verdad, el shell no es la mejor herramienta para procesar archivos.
Awk
Para más de unas pocas líneas (más de unos pocos 10) es mejor usar un lenguaje de programación real. Una solución awk podría ser:
#!/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
Que toma solo 0.2 segundos para el mismo archivo de 6000 líneas mencionado anteriormente.
Comprenda que los <"$2"
archivos for podrían cambiarse nuevamente <<<"$2"
por líneas dentro de variables de shell.
Perl
La solución más rápida es 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 desea ordenar un cambio de archivo <<<"$a"
simplemente "$a"
y agregar -i
a las opciones de perl para que la edición del archivo esté "en su lugar":
#!/bin/bash
perlsort(){ perl -lpi -e '$_=join("'"$1"'",sort {$a <=> $b} split(/['"$1"']/))' "$2"; }
perlsort '.' infile; exit