【发布时间】:2014-03-30 02:06:28
【问题描述】:
我有一个看起来像这样的文件:
20 30 40
80 70 60
50 30 40
每一列代表一个过程。我想知道每一行的程序是如何进行的。我的理想输出是
3 2 1
1 2 3
1 3 2
即在第 1 行中,第三列的值最高,其次是第二列,然后是第一列的最小值(这可以颠倒,没关系)。
我该怎么做?
【问题讨论】:
我有一个看起来像这样的文件:
20 30 40
80 70 60
50 30 40
每一列代表一个过程。我想知道每一行的程序是如何进行的。我的理想输出是
3 2 1
1 2 3
1 3 2
即在第 1 行中,第三列的值最高,其次是第二列,然后是第一列的最小值(这可以颠倒,没关系)。
我该怎么做?
【问题讨论】:
我会使用其他一些 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
【讨论】:
while read line; do for i in $line; do cat -n <(echo "$line" | sed 's/ /\n/g' | sort -r -k +2) | grep "$i$" | { read a b; echo "$a"; }; done | tr '\n' ' '; echo; done
使用 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
【讨论】:
使用 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
【讨论】:
如果您有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
【讨论】:
0.880435 出现两次,因此密钥被覆盖。让我试着修复它。
通过 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";
}
【讨论】: