Vỏ
Tải một ngôn ngữ cấp cao hơn cần có thời gian.
Đối với một vài dòng, chính vỏ có thể là một giải pháp.
Chúng ta có thể sử dụng lệnh bên ngoài sort
và của lệnh tr
. Một là khá hiệu quả trong việc sắp xếp các dòng và cái còn lại là hiệu quả để chuyển đổi một dấu phân cách thành dòng mới:
#!/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'
Điều này cần bash vì <<<
chỉ sử dụng . Nếu điều đó được thay thế bằng một tài liệu ở đây, giải pháp là hợp lệ cho posix.
Đây là khả năng sắp xếp trường bằng tab, khoảng trống hoặc ký tự vỏ glob ( *
, ?
, [
). Không phải dòng mới vì mỗi dòng đang được sắp xếp.
Thay đổi <<<"$2"
để <"$2"
xử lý tên tệp và gọi nó như sau:
shsort '.' infile
Dấu phân cách là giống nhau cho toàn bộ tập tin. Nếu đó là một hạn chế, nó có thể được cải thiện.
Tuy nhiên, một tệp chỉ với 6000 dòng mất 15 giây để xử lý. Quả thực, shell không phải là công cụ tốt nhất để xử lý tệp.
Awk
Đối với nhiều hơn một vài dòng (hơn một vài 10), tốt hơn là sử dụng ngôn ngữ lập trình thực sự. Một giải pháp awk có thể là:
#!/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
Chỉ mất 0,2 giây cho cùng một tệp 6000 dòng được đề cập ở trên.
Hiểu rằng các <"$2"
tệp cho có thể được thay đổi trở lại <<<"$2"
cho các dòng bên trong các biến shell.
Perl
Giải pháp nhanh nhất là 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'
Nếu bạn muốn sắp xếp một thay đổi tệp <<<"$a"
thành đơn giản "$a"
và thêm -i
vào các tùy chọn perl để làm cho phiên bản tệp "tại chỗ":
#!/bin/bash
perlsort(){ perl -lpi -e '$_=join("'"$1"'",sort {$a <=> $b} split(/['"$1"']/))' "$2"; }
perlsort '.' infile; exit