bash 在bash中按多列排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41231186/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sort by multiple columns in bash
提问by Alex
I have a file with 2 columns, "Name" and "Age", looking like this:
我有一个包含 2 列“名称”和“年龄”的文件,如下所示:
Alex, 15
Mary, 12
Alex, 28
Zoe, 16
Alex, 17
I will sort by the first column in alphabetical order, using sort -t ',' -k1,1 filename.txt
, but if there are same names, I want the 2nd column to be sorted in the reversed way of how they were in the original file, like this:
我将按字母顺序按第一列排序,使用sort -t ',' -k1,1 filename.txt
, 但如果有相同的名称,我希望第二列以它们在原始文件中的相反方式排序,如下所示:
Alex, 17
Alex, 28
Alex, 15
Mary, 12
Zoe, 17
How can I do this?
我怎样才能做到这一点?
回答by Tomá? ?íma
Read file from back, sort by the first column and -s to preserve order in case of same value
从后面读取文件,按第一列和 -s 排序以在相同值的情况下保留顺序
tac filename.txt | sort -k1,1 -s
...
Alex, 17
Alex, 28
Alex, 15
Mary, 12
Zoe, 16
回答by gct
Not sure why you'd want to do this! But you could do it in python pretty easily (doesn't preserve whitespace):
不知道你为什么要这样做!但是你可以很容易地在 python 中做到这一点(不保留空格):
import sys
entries = [tuple(map(lambda x: x.strip(), line.strip().split(","))) for line in sys.stdin]
names,ages = zip(*entries)
def compare(a,b):
res = cmp(a[0], b[0])
if (res == 0):
return -cmp(ages.index(a[1]), ages.index(b[1]))
return res
print "\n".join("%s %s" % (name,age) for name,age in sorted(entries, cmp=compare))
回答by lqxyz
sort -t ',' -k1,1 -k2,2r filename.txt
or
或者
sort -t ',' -k1,1 -k2r,2 filename.txt
The output is:
输出是:
Alex, 28
Alex, 17
Alex, 15
Mary, 12
Zoe, 16
Explain: -t
is to specify the field-separator, -k
can be used to specify the start and stop position of field, and we could add a single letter OPTS
for that field for ordering, for example r
means to reverse the result of comparisons.
说明:-t
是指定字段分隔符,-k
可用于指定字段的开始和结束位置,我们可以OPTS
为该字段添加单个字母进行排序,例如r
表示将比较结果颠倒。
回答by piarston
Wops it seems I misunderstood your problem. I cannot find of a magic command, but a little script might do the job:
哇,看来我误解了你的问题。我找不到魔术命令,但一个小脚本可能会完成这项工作:
#! /bin/bash
declare names_sorted=$(cut -d, -f1 filename.txt | sort -k1,1 | uniq)
for name in $names_sorted ; do
grep "$name," filename.txt | tac
done
Quick explanation:
快速解释:
- first we assemble the sorted list of names:
$names_sorted
. - next (assuming the names do not contain white-spaces), we grep each name from the original list and revert that order with the command
tac
- 首先我们组装名称的排序列表:
$names_sorted
。 - 接下来(假设名称不包含空格),我们从原始列表中 grep 每个名称并使用命令恢复该顺序
tac
Hope it's what you wanted this time ;-)
希望这次是你想要的 ;-)
回答by piarston
This should gives what you want:
这应该给你想要的:
sort -k1,1 -k2,2 filename.txt