根据列值对行进行排序

根据列值对行进行排序

我需要根据第二列中包含的数字从最小到最大对 csv 填充中的所有行进行排序,忽略第一行(标题行):

ID(Prot),   ID(lig),    ID(cluster),    dG(rescored),   dG(before), POP(before)
10V1,   lig1,   1,  0.893101,   -7.2300,    36
10V1,   lig1,   3,  1.04024,    -6.5800,    4
10V1,   lig1,   4,  1.03044,    -6.5200,    7
10V1,   lig10,  1,  0.895754,   -6.0300,    47
10V1,   lig10,  2,  0.668236,   -5.9500,    112
10V1,   lig10,  3,  1.0103, -5.8200,    19
10V1,   lig1001,    1,  0.594972,   -5.6500,    142
10V1,   lig1001,    2,  1.05779,    -5.5000,    10
10V1,   lig1001,    3,  1.11195,    -4.9500,    2
10V1,   lig3,   1,  1.01583,    -5.6000,    20
10V1,   lig3,   2,  0.972203,   -5.2600,    36
10V1,   lig3,   3,  0.694967,   -5.2400,    118
10V1,   lig8,   1,  0.931977,   -7.4000,    25
10V1,   lig8,   2,  1.00413,    -7.1100,    9

应按 lig1、lig3、lig8、lig10、lig1001 等排序:

ID(Prot),   ID(lig),    ID(cluster),    dG(rescored),   dG(before), POP(before)
    10V1,   lig1,   1,  0.893101,   -7.2300,    36
    10V1,   lig1,   3,  1.04024,    -6.5800,    4
    10V1,   lig1,   4,  1.03044,    -6.5200,    7
    10V1,   lig3,   1,  1.01583,    -5.6000,    20
    10V1,   lig3,   2,  0.972203,   -5.2600,    36
    10V1,   lig3,   3,  0.694967,   -5.2400,    118
    10V1,   lig8,   1,  0.931977,   -7.4000,    25
    10V1,   lig8,   2,  1.00413,    -7.1100,    9
    10V1,   lig10,  1,  0.895754,   -6.0300,    47
    10V1,   lig10,  2,  0.668236,   -5.9500,    112
    10V1,   lig10,  3,  1.0103, -5.8200,    19
    10V1,   lig1001,    1,  0.594972,   -5.6500,    142
    10V1,   lig1001,    2,  1.05779,    -5.5000,    10
    10V1,   lig1001,    3,  1.11195,    -4.9500,    2

我试过了

sort -k2.4,2n "${csv}" > sorted.csv

但它不能正确识别第二个值。

答案1

默认情况下,sort识别由非空白到空白转换分隔的字段。第二行的第二个字段(第一个是标题)不是 也不是lig1lig1,而是lig1,

一开始并不清楚这个字段是否包含前导空格或制表符,因为这个网站在以下情况下将制表符转换为多个空格:显示代码。原料来源告诉我每行的第二个字段包含一个前导制表符。

此制表符算作字段中的第一个字符,因此您的-k2.4,2n数字少了一个。它应该是-k2.5,2n

为了可靠地先打印标题而不对其进行排序,请让某些东西在sort处理其余部分之前读取并打印它。它可以是你的 shell:

{ IFS= read -r line; printf '%s\n' "$line"; sort -k2.5,2n; } <"${csv}"

或者可以是head

{ head -n 1; sort -k2.5,2n; } <"${csv}"

在我的 Debian 10 中,这两个命令在从常规文件读取时都运行良好。从管道读取时(例如cat "${csv}" | { head …),head显然可能会读取过多并丢弃过多数据(因此sort无法获取,数据会丢失)。

猜测 head即使从常规文件读取时也会读取更多内容,它只是在退出之前返回正确的位置,因此下一个工具可以从那里接管;对于不可搜索的输入,这显然是不可能的。

read更加小心并且总是一次读取一个字节,因此它不会读取太多。

相关内容