Conchiglia
Il caricamento di una lingua di livello superiore richiede tempo.
Per poche righe, la shell stessa potrebbe essere una soluzione.
Possiamo usare il comando esterno sort
e il comando tr
. Uno è abbastanza efficiente nelle linee di smistamento e l'altro è efficace per convertire un delimitatore in newline:
#!/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'
Questo bisogno bash a causa dell'uso di <<<
solo. Se questo viene sostituito con un here-doc, la soluzione è valida per posix.
Questo è in grado di ordinare i campi con tabulazioni, spazi o caratteri shell glob ( *
, ?
, [
). Non newline perché ogni riga viene ordinata.
Passare <<<"$2"
a <"$2"
elaborare i nomi dei file e chiamarlo come:
shsort '.' infile
Il delimitatore è lo stesso per l'intero file. Se questa è una limitazione, potrebbe essere migliorata.
Tuttavia, l'elaborazione di un file con solo 6000 righe richiede 15 secondi. In verità, la shell non è lo strumento migliore per elaborare i file.
awk
Per più di alcune righe (più di qualche decina) è meglio usare un vero linguaggio di programmazione. Una soluzione awk potrebbe essere:
#!/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
Ciò richiede solo 0,2 secondi per lo stesso file di 6000 righe sopra menzionato.
Comprendi che i <"$2"
file for potrebbero essere cambiati nuovamente <<<"$2"
per le righe all'interno delle variabili della shell.
Perl
La soluzione più veloce è il 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'
Se si desidera ordinare una modifica del file <<<"$a"
in semplicemente "$a"
e aggiungere -i
alle opzioni perl per rendere "in atto" l'edizione del file:
#!/bin/bash
perlsort(){ perl -lpi -e '$_=join("'"$1"'",sort {$a <=> $b} split(/['"$1"']/))' "$2"; }
perlsort '.' infile; exit