如何根据多个不同列的递增值对多个值范围进行排序?

时间:2018-11-22 07:36:36

标签: linux shell perl awk

我在对input.txt文件中的某些值进行排序时遇到问题,但我仍然不知道如何解决它。

输入文件(input.txt):

1 5 1 2183 2006 6001 6132
1 6 1 2183 2006 6001 6133
1 7 1 2183 2006 6001 6134
...
1 65 1 2183 2006 6001 6227
1 66 1 2183 2006 6001 6234
1 67 1 2183 2006 6001 6235
1 68 1 2183 2006 6004 6156
1 69 1 2183 2006 6004 6157
1 70 1 2183 2006 6004 6158
...
1 115 1 2183 2006 6004 6227
1 116 1 2183 2006 6004 6234
1 117 1 2183 2006 6004 6235
1 118 1 2183 2006 6007 6120
1 119 1 2183 2006 6007 6146
1 120 1 2183 2006 6007 6147
...
1 182 1 2183 2006 6007 6237
1 183 1 2183 2006 6007 6238
1 184 1 2183 2006 6007 6239

所需的输出文件(output.txt):

1 2183 2006 5-67 6001 6132 6235
1 2183 2006 68-117 6004 6156 6235
1 2183 2006 118-184 6007 6120 6239

输入文件中有7列/字段。第1、3、4、5列应为常数。第2列和第6列的更改取决于第7列。第6列的增量值为3,第7列的更改是变化的,仅在最后3位数字变化。示例6 132 ,6 133 ,6 134

诀窍在于输出第4列,如何根据输入第6列和第7列的更改对其排序和取消排序?

  

假设是否:

     

输入列6(6001)和输入列7(6132)到达最后一个   下一个输入列6(6004)和输入列7(6235)之前的值

     

然后,最终输出列4的值应为5-67,输出列   5应该具有相同的值6001,输出列6应该具有   第一输入列7和输出列7(6132)应该具有   最后输入第7列(6235)。

Example 1st batch:

Input:
1 5 1 2183 2006 6001 6132
1 6 1 2183 2006 6001 6133
1 7 1 2183 2006 6001 6134
...
1 65 1 2183 2006 6001 6227
1 66 1 2183 2006 6001 6234
1 67 1 2183 2006 6001 6235

Desired Output:
1 2183 2006 5-67 6001 6132 6235


Example 2nd batch:
Input:
1 68 1 2183 2006 6004 6156
1 69 1 2183 2006 6004 6157
1 70 1 2183 2006 6004 6158
...
1 115 1 2183 2006 6004 6227
1 116 1 2183 2006 6004 6234
1 117 1 2183 2006 6004 6235

Desired Output:
1 2183 2006 68-117 6004 6156 6235


Example 3rd batch:

Input:
1 118 1 2183 2006 6007 6120
1 119 1 2183 2006 6007 6146
1 120 1 2183 2006 6007 6147
...
1 181 1 2183 2006 6007 6236
1 182 1 2183 2006 6007 6237
1 183 1 2183 2006 6007 6238
1 184 1 2183 2006 6007 6239

Desired Output:
1 2183 2006 118-184 6007 6120 6239

编译所需的输出时,它应如下所示:

1 2183 2006 5-67 6001 6132 6235
1 2183 2006 68-117 6004 6156 6235
1 2183 2006 118-184 6007 6120 6239

请问您对此有何建议?

2 个答案:

答案 0 :(得分:3)

您想要分组的列数据行,并找到诸如screams数据库的最小值和最大值之类的东西。所以...脚本sqlite3:

#!/bin/sh
sqlite3 -batch -noheader -list -separator ' ' <<EOF
CREATE TABLE data(c1 INTEGER, c2 INTEGER, c3 INTEGER, c4 INTEGER
                , c5 INTEGER, c6 INTEGER, c7 INTEGER);
.import "$1" data
SELECT c1, c4, c5, min(c2) || '-' || max(c2), c6, min(c7), max(c7)
FROM data GROUP BY c6 ORDER BY c6;
EOF

使用您的示例输入:

$ ./doit.sh input.txt
1 2183 2006 5-67 6001 6132 6235
1 2183 2006 68-117 6004 6156 6235
1 2183 2006 118-184 6007 6120 6239

答案 1 :(得分:1)

$6 != col6 {
    printf fmt, min2, max2, min7, max7
    fmt = $1 " " $4 " " $5 " %d-%d " $6 " %d %d\n"

    min2 = max2 = $2
    min7 = max7 = $7

    col6 = $6
}
{
    if ($2 < min2)
        min2 = $2
    else if ($2 > max2)
        max2 = $2

    if ($7 < min7)
        min7 = $7
    else if ($7 > max7)
        max7 = $7
}
END {
    printf fmt, min2, max2, min7, max7
}