Оболонка
Завантаження мови вищого рівня потребує часу.
Для кількох рядків сама оболонка може бути рішенням.
Ми можемо використовувати зовнішню команду sort
та команду tr
. Один досить ефективний при сортуванні ліній, а інший ефективний для перетворення одного роздільника в нові рядки:
#!/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'
Це потрібно баш через використання <<<
тільки. Якщо це замінено на тут-doc, рішення дійсне для posix.
Це може сортувати поля з закладками, пробілами або оболонки Глоби символами ( *
, ?
, [
). Не нові рядки, тому що кожен рядок сортується.
Змініть, <<<"$2"
щоб <"$2"
обробити назви файлів і назвіть це так:
shsort '.' infile
Розмежувач однаковий для всього файлу. Якщо це обмеження, воно може бути покращене.
Однак обробка файлу, що містить лише 6000 рядків, займає 15 секунд. Дійсно, оболонка - не найкращий інструмент для обробки файлів.
Awk
Для більш ніж декількох рядків (більше кількох 10-х) краще використовувати справжню мову програмування. Рішенням awk може бути:
#!/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
Що займає всього 0,2 секунди для того самого файлу 6000 рядків, згаданого вище.
Зрозумійте, що <"$2"
для файлів можна змінити назад <<<"$2"
для рядків всередині змінних оболонок.
Perl
Найшвидше рішення - 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'
Якщо ви хочете сортувати зміну файлу <<<"$a"
просто "$a"
та додайте -i
до параметрів perl, щоб зробити видання файлу "на місці":
#!/bin/bash
perlsort(){ perl -lpi -e '$_=join("'"$1"'",sort {$a <=> $b} split(/['"$1"']/))' "$2"; }
perlsort '.' infile; exit