我有一个名单,名单上的名字是不正常的。如何使用字母部分的自定义排序顺序,使它们符合正确的字母数字顺序?
我的文件numbers.txt
alpha-1
beta-3
alpha-10
beta-5
alpha-5
beta-1
gamma-7
gamma-1
delta-10
delta-2主要的一点是,我的脚本应该认识到,它应该在beta之前打印beta,在gamma之前打印beta,在delta之前打印gamma。
也就是说,单词应该根据它们所代表的希腊字母的顺序进行排序。
预期订单:
alpha-1
alpha-5
alpha-10
beta-1
beta-3
beta-5
gamma-1
gamma-7
delta-2
delta-10PS:我试过用sort -n numbers.txt,但它不符合我的需要。
发布于 2017-01-23 15:23:37
您可以使用辅助awk命令,如下所示:
awk -F- -v keysInOrder="alpha,beta,gamma,delta" '
BEGIN {
split(keysInOrder, a, ",")
for (i = 1; i <= length(a); ++i) keysToOrdinal[a[i]] = i
}
{ print keysToOrdinal[$1] "-" $0 }
' numbers.txt | sort -t- -k1,1n -k3,3n | cut -d- -f2-awk命令用于:- map the custom keys onto numbers that reflect the desired sort order; note that the full list of keys must be passed via variable `keysInOrder`, in order.
- prepend the numbers to the input as an auxiliary column, using separator `-` too; e.g., `beta-3` becomes `2-beta-3`, because `beta` is in position _2_ in the ordered list of sort keys.
sort根据映射的数字和第二列中的原始数字对awk的输出进行排序,得到所需的自定义排序顺序。cut移除辅警。又是映射数字。发布于 2017-01-23 15:24:00
我想在这里找到Perl。此脚本将起作用:
#!/usr/bin/env perl
use v5.14; # turn on modern features
# Greek alphabet
my @greek_letters =qw(alpha beta gamma delta epsilon zeta
eta theta iota kappa lambda mu
nu xi omicron pi rho sigma
tau upsilon phi chi psi omega);
# An inverted map from letter name to position number;
# $number{alpha} = 1, $number{beta} = 2, etc:
my %number;
@number{@greek_letters} = 1..@greek_letters;
# Read the lines to sort
chomp(my @lines = <>);
# split on hyphen into arrays of individual fields
my @rows = map { [ split /-/ ] } @lines;
# prepend the numeric position of each item's Greek letter
my @keyed = map { [ $number{$_->[0]}, @$_ ] } @rows;
# sort by Greek letter position (first field, index 0) and then
# by final number (third field, index 2)
my @sorted = sort { $a->[0] <=> $b->[0]
|| $a->[2] <=> $b->[2] } @keyed;
# remove the extra field we added
splice(@$_, 0, 1) for @sorted;
# combine the fields back into strings and print them out
say join('-', @$_) for @sorted;将Perl代码保存到一个文件(例如,greeksort.pl)中,并运行perl greeksort.pl numbers.txt以获得排序的输出。
发布于 2017-01-23 16:16:04
这里有一个Python解决方案。不要试图用Bash,sed,awk来做困难的事情。您通常可以完成您想要的,但它将更加混乱,更容易出错,更难维护。
#!/usr/bin/env python3
# Read input lines
use_stdin = True
if use_stdin:
import sys
lines = sys.stdin.read().strip().split()
else:
# for testing
with open('numbers.txt') as input:
lines = input.read().strip().split()
# Create a map from greek letters to integers for sorting
greek_letters = """alpha beta gamma delta epsilon zeta
eta theta iota kappa lambda mu
nu xi omicron pi rho sigma
tau upsilon phi chi psi omega"""
gl = greek_letters.strip().split()
gl_map = {letter:rank for rank, letter in enumerate(gl)}
# Split each line into (letter, number)
a = (x.split('-') for x in lines)
b = ((s, int(n)) for s,n in a)
# Using an order-preserving sort, sort by number, then letter
by_number = lambda x: x[1]
by_greek_letter = lambda x: gl_map.get(x[0])
c = sorted(sorted(b, key=by_number), key=by_greek_letter)
# Re-assemble and print
for s,n in c:
print('-'.join((s, str(n))))https://stackoverflow.com/questions/41804397
复制相似问题