按隐藏在文件中的数值对文件中的行进行排序

按隐藏在文件中的数值对文件中的行进行排序

我正在编写一个 Bash 脚本来使用工具测试 USB 闪存是否有错误f3。我有这样的文本(通过从f3read程序中 grep 日志创建):

2017-10-25_09:30:22/sdf.log:Data LOST: 4.00 KB (8 sectors)
2017-10-25_09:30:22/sdi.log:Data LOST: 5.00 KB (10 sectors)
2017-10-25_09:30:22/sdj.log:Data LOST: 2.35 MB (4822 sectors)
2017-10-25_09:30:22/sdn.log:Data LOST: 5.00 KB (10 sectors)
2017-10-25_09:30:22/sdo.log:Data LOST: 4.00 KB (8 sectors)
2017-10-25_09:30:22/sdp.log:Data LOST: 4.00 KB (8 sectors)
2017-10-25_09:30:22/sdq.log:Data LOST: 2.00 KB (4 sectors)
2017-10-25_14:37:03/sdb.log:Data LOST: 5.00 KB (10 sectors)
2017-10-25_14:37:03/sdc.log:Data LOST: 3.00 KB (6 sectors)
2017-10-26_09:17:59/sdd.log:Data LOST: 3.00 KB (6 sectors)
2017-10-26_09:17:59/sde.log:Data LOST: 2.00 KB (4 sectors)
2017-10-26_09:17:59/sdf.log:Data LOST: 3.00 KB (6 sectors)
2017-10-26_09:17:59/sdg.log:Data LOST: 6.00 KB (12 sectors)
2017-10-26_09:17:59/sdh.log:Data LOST: 611.29 MB (1251918 sectors)
2017-10-26_09:17:59/sdi.log:Data LOST: 6.00 KB (12 sectors)
2017-10-26_09:17:59/sdl.log:Data LOST: 6.00 KB (12 sectors)
2017-10-26_09:17:59/sdo.log:Data LOST: 3.00 KB (6 sectors)
2017-10-26_09:17:59/sdp.log:Data LOST: 2.00 KB (4 sectors)
2017-10-26_09:17:59/sdq.log:Data LOST: 414.60 MB (849106 sectors)
2017-10-26_09:17:59/sdr.log:Data LOST: 65.29 MB (133712 sectors)
2017-10-26_09:17:59/sds.log:Data LOST: 5.00 KB (10 sectors)

我想按行末尾指出的坏扇区数量对行进行排序。我尝试使用sort,但我不知道如何使用它的--key选项来使其执行我想要的操作。

我不能先剪掉这些行,因为我需要提取驱动器名称(sda、sdb 等)以用于报告。

答案1

POSIXly,你可以这样做:

sort -t '(' -k2n < file

即将字段分隔符设置为(并对第二个字段(或者更确切地说以第二个字段开头的行的部分)进行数字排序。

或者,您可以保留第5 个字段的默认字段分隔符(从非空白到空白的过渡)" (12"并使用:

sort -k5.3n < file

(即,对从第 5个字段的第 3字符开始的行部分进行数字排序)。

对于平局,最后的排序顺序开始发挥作用,这就是整行的词汇比较(这里可以方便地为您提供时间顺序)。

如果您想按驱动器名称对关系进行排序,您可以使用:

sort -t '(' -k2n -k1.21

(第二个键是从第21 个字符开始的行部分,词法比较)

答案2

sort -V如果该选项可用则使用

-V, --版本排序

文本中(版本)数字的自然排序

$ <cmd> | sort -k5,5V
2017-10-25_09:30:22/sdq.log:Data LOST: 2.00 KB (4 sectors)
2017-10-26_09:17:59/sde.log:Data LOST: 2.00 KB (4 sectors)
2017-10-26_09:17:59/sdp.log:Data LOST: 2.00 KB (4 sectors)
2017-10-25_14:37:03/sdc.log:Data LOST: 3.00 KB (6 sectors)
2017-10-26_09:17:59/sdd.log:Data LOST: 3.00 KB (6 sectors)
2017-10-26_09:17:59/sdf.log:Data LOST: 3.00 KB (6 sectors)
2017-10-26_09:17:59/sdo.log:Data LOST: 3.00 KB (6 sectors)
2017-10-25_09:30:22/sdf.log:Data LOST: 4.00 KB (8 sectors)
2017-10-25_09:30:22/sdo.log:Data LOST: 4.00 KB (8 sectors)
2017-10-25_09:30:22/sdp.log:Data LOST: 4.00 KB (8 sectors)
2017-10-25_09:30:22/sdi.log:Data LOST: 5.00 KB (10 sectors)
2017-10-25_09:30:22/sdn.log:Data LOST: 5.00 KB (10 sectors)
2017-10-25_14:37:03/sdb.log:Data LOST: 5.00 KB (10 sectors)
2017-10-26_09:17:59/sds.log:Data LOST: 5.00 KB (10 sectors)
2017-10-26_09:17:59/sdg.log:Data LOST: 6.00 KB (12 sectors)
2017-10-26_09:17:59/sdi.log:Data LOST: 6.00 KB (12 sectors)
2017-10-26_09:17:59/sdl.log:Data LOST: 6.00 KB (12 sectors)
2017-10-25_09:30:22/sdj.log:Data LOST: 2.35 MB (4822 sectors)
2017-10-26_09:17:59/sdr.log:Data LOST: 65.29 MB (133712 sectors)
2017-10-26_09:17:59/sdq.log:Data LOST: 414.60 MB (849106 sectors)
2017-10-26_09:17:59/sdh.log:Data LOST: 611.29 MB (1251918 sectors)

答案3

我已经找到了。

sort -n -t '(' -k2V

-n告诉 sort 读取字符串中的数值

-t '('告诉它使用(字符作为字段分隔符。因为这个词部门)以后总是一样的,不会影响排序顺序。

-k2V定义自定义键,使用第二列(第一个(字符后的文本)进行排序。

答案4

稍微更灵活的解决方案提取扇区计数,将其复制到行的开头,排序,最后再次删除重复的部分:

sed 's/^.*(\([0-9]\{1,\} \)sectors)$/\1&/' |
  sort -n |
  cut -d ' ' -f 2-

此解决方案更加灵活,因为它适用于标识每个记录中的排序键的任意模式。

相关内容