0

我有一个这样的 CSV 文件:

fish,4
cat,1
elephant,1
tree,2
dog,8
car,10

awk -F',' '{print length($1),$0}' file.csv | sort -k1nr | cut -d' ' -f 2-对于第一列中出现的所有单词,将按字长对文件进行排序:

elephant,1
fish,4
tree,2
cat,1
dog,8
car,10

sort -t, -k+2 -n -r file.csv将根据第二列中出现的数字从大到小对文件进行排序:

car,10
dog,8
fish,4
tree,2
elephant,1
cat,1

如何将这两个命令一起使用,以便 CSV 文件首先根据第一列中出现的单词按字长排序,然后根据出现在第一列中的任何包含相同长度单词的行进行排序第二列从大到小。结果输出如下所示:

elephant,1
fish,4
tree,2
car,10
dog,8
cat,1

这两种排序方法如何一起使用?

4

3 回答 3

5

试试这一行:

awk -F, '{print length($1)","$0}' file|sort -t, -rn  -k1 -k3|sed 's/[^,],//'

会给你:

elephant,1
fish,4
tree,2
car,10
dog,8
cat,1

想法是,首先将 col1 的长度添加到输出中,然后将 awk 的输出用两列排序,最后删除添加的长度列(第一列)以获得最终结果。

于 2013-07-09T08:30:06.973 回答
1

如果您使用的是,那么您可以使用asort函数来执行排序,因此无需调用其他实用程序。你可以尝试这样的事情:

awk -F, 'function cmp(i1,v1,i2,v2) {split(v1,a1); split(v2,a2)
  l1=length(a1[1]); l2=length(a2[1])
  return l1 > l2 ? -1 : l1 < l2 ? 1 : a1[2] > a2[2] ? -1 : a1[2] < a2[2]
}
{a[n++]=$0}
END{asort(a,a,"cmp"); for(i in a) print a[i]}' infile

输出:

elephant,1
fish,4
tree,2
car,10
dog,8
cat,1

该脚本首先读取所有行,然后a对函数调用的数组进行排序cmp。我使用的唯一技巧是为ora > b返回通常的 1 或 0 。truefalse

中的较短版本:

perl -F, -ane 'push @a,[@F]; 
  END{for $i(sort {length $b->[0]<=>length $a->[0] or $b->[1]<=>$a->[1]} @a) {printf "%s,%d\n", @$i}
}' infile

这不是 100% 正确的,因为它$F[1]包含\n,但printf可以正确处理。

于 2013-07-09T09:05:13.970 回答
0

颠倒排序的顺序,然后用 使第二个排序稳定-s

于 2013-07-09T08:23:26.450 回答