根据bash中的模式对文件行进行排序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了根据bash中的模式对文件行进行排序相关的知识,希望对你有一定的参考价值。

我有一个包含以下行的文件:

This test took 1201ms to execute
The IO operation cost 113ms
Main thread have been executing for 16347ms

如何根据ms旁边的数字对它们进行排序?

我使用了以下sed命令,但没有用

sed -r 's/[[:digit]]+ms//g' file.txt | sort -r | > tmp
答案
$ awk '{match($0,/[[:digit:]]+ms/,a)}{print substr(a[0], 1, length(a[0])-2),$0}' inputFile | sort -nk1 | cut -f2- -d ' '
The IO operation cost 113ms
This test took 1201ms to execute
Main thread have been executing for 16347ms

awk匹配[[:digit:]]ms并将其打印(除了最后两个字符ms)到行的开头,sort使用第一个字段。 cut后来删除了第一个字段并返回原始行。

另一答案

GNU awk

awk 'BEGIN {PROCINFO["sorted_in"]="@ind_num_asc"} 
        {idx=gensub(".*\s+([0-9]+).*", "\1", "g"); arr[idx]=$0} 
          END{for (i in arr) print arr[i]}' file.txt
  • PROCINFO["sorted_in"]="@ind_num_asc"变量设置基于数字索引的(关联)数组排序顺序
  • {idx=gensub(".*\s+([0-9]+).*", "\1", "g"); arr[idx]=$0}获取数字并使它们成为关联数组arr的索引,其值为相应的记录
  • END{for (i in arr) print arr[i]}打印数组值

如果要将排序顺序反转为降序,请执行以下操作:

PROCINFO["sorted_in"]="@ind_num_desc"

例:

% cat file.txt
This test took 1201ms to execute
The IO operation cost 113ms
Main thread have been executing for 16347ms

% awk 'BEGIN {PROCINFO["sorted_in"]="@ind_num_asc"} {idx=gensub(".*\s+([0-9]+).*", "\1", "g"); arr[idx]=$0} END{for (i in arr) print arr[i]}' file.txt
The IO operation cost 113ms
This test took 1201ms to execute
Main thread have been executing for 16347ms
另一答案

使用GNU awk(gawk):

$ awk 'BEGIN{PROCINFO["sorted_in"]="@val_num_asc"} {for (i=1;i<=NF;i++) if ($i~/ms$/){a[$0]=$i+0; break}} END{for (line in a)print line}' file.txt
The IO operation cost 113ms
This test took 1201ms to execute
Main thread have been executing for 16347ms

这个怎么运作

  • BEGIN{PROCINFO["sorted_in"]="@val_num_asc"} 这告诉awk按数组值按升序对数组进行排序。这是一个GNU功能。
  • for (i=1;i<=NF;i++) if ($i~/ms$/){a[$0]=$i+0; break} 对于一行中的每个字段,我们看看它是否以ms结尾。如果确实如此,我们将关键数字a分配给等于整行的键下的该字段的值。
  • END{for (line in a)print line} 在我们读完整个文件后,我们打印出数组a的键。由于数组a按值按升序排序,因此打印输出按时间按升序排列。
另一答案

您可以使用sed提取数字部分并使用分隔符将其放在行的开头,然后使用sort将其放在第一个字段中,并使用cut删除添加的字段:

sed -E 's/^(.*) ([[:digit:]]+)ms(.*)$/2|1 2ms3/' file | # extract ms and place it at the beginning
  sort -t '|' -k1,1n |                                      # sort it by the field added above
  cut -f2- -d '|'                                           # remove the field

输出:

The IO operation cost 113ms
This test took 1201ms  to execute
Main thread have been executing for 16347ms

以上是关于根据bash中的模式对文件行进行排序的主要内容,如果未能解决你的问题,请参考以下文章

根据包含数字和不包含数字的行对 CSV 中的行进行排序

根据核心数据中的属性对实体中的行进行排序

Bash:按前 4 列对 csv 文件进行排序

如何允许对不在编辑模式下的 SwiftUI 列表中的行进行重新排序?

Pandas 根据列中的最小值到最大值对行进行重新排序

如何在bash中对逗号分隔的值进行排序?