Сортировка значений и вывод индексов их отсортированных столбцов

66
1

У меня есть файл, который выглядит так:

20 30 40
80 70 60
50 30 40

Каждый столбец представляет собой процедуру. Я хочу знать, как выполнялись процедуры для каждой строки. Мой идеальный выход был бы

3 2 1
1 2 3
1 3 2

т.е. в строке 1, третий столбец имел наивысшее значение, затем второе, затем первое наименьшее (это может быть обратное, не имеет значения).

Как мне это сделать?

спросил(а) 2014-02-27T01:39:00+04:00 6 лет, 4 месяца назад
1
Решение
67

Я бы сделал это с помощью некоторых других инструментов Unix (read, cat, sort, cut, tr, sed и bash конечно):

while read line
do
cat -n <(echo "$line" | sed 's/ /\n/g') | sort -r -k +2 | cut -f1 | tr '\n' ' '
echo
done < input.txt

Результат выглядит следующим образом:

 3      2      1 
1 2 3
1 3 2

ответил(а) 2014-02-27T01:55:00+04:00 6 лет, 4 месяца назад
55

Использование Gnu Awk версии 4:


$ awk 'BEGIN{ PROCINFO["sorted_in"]="@val_num_desc" }
{
split($0,a," ")
for (i in a) printf "%s%s", i,OFS
print ""
}' file

3 2 1
1 2 3
1 3 2

ответил(а) 2014-03-01T16:22:00+04:00 6 лет, 4 месяца назад
55

Другое решение с использованием Python:

$ python
Python 2.7.6 (default, Jan 26 2014, 17:25:18)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> with open('file.txt') as f:
... lis=[x.split() for x in f]
...
>>> for each in lis:
... each = [i[0] + 1 for i in sorted(enumerate(each), key=lambda x:x[1], reverse=True)]
... print ' '.join([str(item) for item in each])
...
3 2 1
1 2 3
1 3 2

ответил(а) 2014-02-27T08:01:00+04:00 6 лет, 4 месяца назад
39

Решение через perl

#!/usr/bin/perl
open(FH,'<','/home/chidori/input.txt') or die "Can't open file$!\n";
while(my $line=<FH>){
chomp($line);
my @unsorted_array=split(/\s/,$line);
my $count=scalar @unsorted_array;
my @sorted_array = sort { $a <=> $b } @unsorted_array;
my %hash=map{$_ => $count--} @sorted_array;

foreach my $value(@unsorted_array){
print "$hash{$value} ";
}

print "\n";
}

ответил(а) 2014-03-01T11:11:00+04:00 6 лет, 4 месяца назад
39

Если у вас есть GNU awk вы можете сделать что-то вроде:

awk '{
y = a = x = j = i = 0;
delete tmp;
delete num;
delete ind;
for(i = 1; i <= NF; i++) {
num[$i, i] = i
}
x = asorti(num)
for(y = 1; y <= x; y++) {
split(num[y], tmp, SUBSEP)
ind[++j] = tmp[2]
}
for(a = x; a >= 1; a--) {
printf "%s%s", ind[a],(a==1?"\n":" ")
}
}' file

$ cat file
20 30 40
0.923913 0.913043 0.880435 0.858696 0.826087 0.902174 0.836957 0.880435
80 70 60
50 30 40

awk '{
y = a = x = j = i = 0;
delete tmp;
delete num;
delete ind;
for(i = 1; i <= NF; i++) {
num[$i, i] = i
}
x = asorti(num)
for(y = 1; y <= x; y++) {
split(num[y], tmp, SUBSEP)
ind[++j] = tmp[2]
}
for(a = x; a >= 1; a--) {
printf "%s%s", ind[a],(a==1?"\n":" ")
}
}' file
3 2 1
1 2 6 8 3 4 7 5
1 2 3
1 3 2

ответил(а) 2014-02-27T02:02:00+04:00 6 лет, 4 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема