如何通过倒数第二个字段对可变数量的字段进行排序?

时间:2015-12-06 23:34:46

标签: linux sorting unix awk scripting

编者注:问题的原始标题提到 tabs 作为字段分隔符。

在诸如

之类的文本中
500 east 23rd avenue Toronto 2 890 400000 1 
900 west yellovillage blvd Mississauga 3 800 600090 3

你会如何按倒数第二列的升序排序?

编者注:OP后来提供了另一个示例输入行500 Jackson Blvd Toronto 3 700 40000 2,它只包含 8 空白分隔的输入字段(与 9相比上面),揭示了在输入中处理变量数量的字段的必要性。

3 个答案:

答案 0 :(得分:3)

注意:有几个可能是单独的问题:

更新:问题 C 是相关问题。

  • 问题A:正如问题标题所暗示的那样:如何使用制表符(\t)作为字段分隔符?

  • 问题B:如果给出固定的号码,如何在不知道该字段的特定索引的情况下,按倒数第二个字段对输入进行排序田地?

  • 问题C:如果给出变量号码,如何在不知道该字段的相应索引的情况下按倒数第二个字段对输入进行排序田地?

回答问题A:

sort-t选项允许您指定字段分隔符。 默认情况下,sort使用任何行内部空格作为分隔符。

假设Bash,Ksh或Zsh,您可以使用ANSI C-quoted string$'...')将单个标签指定为字段分隔符($'\t'):

sort -t $'\t' -n -k8,8 file # -n sorts numerically; omit for lexical sorting

回答问题B:

注意:这假定所有输入行都有相同个字段,并且该输入来自文件file

 # Determine the index of the next-to-last column, based on the first
 # line, using Awk:
 nextToLastColNdx=$(head -n 1 file | awk -F '\t' '{ print NF - 1 }')

 # Sort numerically by the next-to-last column (omit -n to sort lexically):
 sort -t $'\t' -n -k$nextToLastColNdx,$nextToLastColNdx file

注意:要按单个字段排序,请始终将其指定为 end 字段(例如,-k8,8),如上所述,因为{{ 1}},仅给出 start 字段索引(例如,sort),从指定字段到行的其余部分进行排序。

回答问题C:

注意:这假设输入行可能有一个变量个字段,并且在每行上该行的倒数第二个字段应该起作用作为排序字段;输入来自文件-k8

file
  • awk '{ printf "%s\t%s\n", $(NF-1), $0 }' file | sort -n -k1,1 | # omit -n to perform lexical sorting cut -f2- 命令提取每行的倒数第二个字段,预先输出到输出的输入行,由制表符分隔。
  • 结果按第一个字段排序(即每个输入行的倒数第二个字段)。
  • 最后,使用awk
  • 再次删除人工添加的排序字段

答案 1 :(得分:0)

我建议看看" man sort"。

您将看到如何指定字段分隔符以及如何指定应该用作排序键的字段索引。

答案 2 :(得分:0)

您可以使用sort -k 2

例如:

echo -e '000 west \n500 east\n500 east\n900 west' | sort -k 2

结果是:

500 east
500 east
900 west
000 west

您可以在排序的手册页中找到更多信息。看一下手册页的结尾。就在作者之前,你有一些有趣的信息:)

再见