我正在编写一个 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-
此解决方案更加灵活,因为它适用于标识每个记录中的排序键的任意模式。