Schale
Das Laden einer höheren Sprache braucht Zeit.
Für einige Zeilen kann die Shell selbst eine Lösung sein.
Wir können den externen Befehl sort
und den Befehl verwenden tr
. Einer ist sehr effizient beim Sortieren von Zeilen und der andere konvertiert effektiv ein Trennzeichen in Zeilenumbrüche:
#!/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'
Dies muss nur wegen der Verwendung von Bash <<<
. Wenn dies durch ein Here-Doc ersetzt wird, gilt die Lösung für posix.
Dies ist in der Lage zu sortieren Felder mit Tabulatoren, Leerzeichen oder der Schale glob Zeichen ( *
, ?
, [
). Keine Zeilenumbrüche, da jede Zeile sortiert wird.
Wechseln Sie <<<"$2"
zu <"$2"
, um Dateinamen zu verarbeiten, und nennen Sie es wie folgt:
shsort '.' infile
Das Trennzeichen ist für die gesamte Datei gleich. Wenn dies eine Einschränkung ist, könnte sie verbessert werden.
Die Verarbeitung einer Datei mit nur 6000 Zeilen dauert jedoch 15 Sekunden. Die Shell ist wirklich nicht das beste Werkzeug, um Dateien zu verarbeiten.
Awk
Für mehr als ein paar Zeilen (mehr als ein paar Zehner) ist es besser, eine echte Programmiersprache zu verwenden. Eine awk-Lösung könnte sein:
#!/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
Dies dauert nur 0,2 Sekunden für dieselbe 6000-Zeilen-Datei, die oben erwähnt wurde.
Verstehen Sie, dass die <"$2"
for-Dateien wieder in <<<"$2"
for-Zeilen innerhalb von Shell-Variablen geändert werden können.
Perl
Die schnellste Lösung ist 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'
Wenn Sie eine Datei ändern möchten, ändern Sie <<<"$a"
sie einfach "$a"
und fügen Sie sie -i
zu Perl-Optionen hinzu, um die Datei-Edition "an Ort und Stelle" zu machen:
#!/bin/bash
perlsort(){ perl -lpi -e '$_=join("'"$1"'",sort {$a <=> $b} split(/['"$1"']/))' "$2"; }
perlsort '.' infile; exit