gpt4 book ai didi

sorting - 连续排序重复数据但行数不同

转载 作者:行者123 更新时间:2023-12-04 14:36:52 24 4
gpt4 key购买 nike

我有以下格式的数据:

2
1
A 11.364500 48.395199 40.160500 5
B 35.067699 30.944700 24.155300 4
4
2
A 26.274099 38.533298 32.624298 4
B 36.459000 29.662701 17.806299 5
A 15.850300 28.130899 24.753901 4
A 32.098000 33.665699 20.372499 4
5
3
A 17.501801 44.279202 8.005670 5
B 35.853001 43.095901 17.402901 4
B 1.326100 17.127600 39.600300 4
A 9.837760 41.103199 13.062300 5
B 31.686800 44.997501 16.619499 4
3
4
B 31.274700 8.726580 25.267599 4
A 19.032400 41.384701 19.456301 5
B 19.441900 24.286400 6.961680 4
1
5
B 48.973999 15.508400 5.099710 4
6
6
A 42.586601 21.343800 23.280701 5
B 30.145800 13.256200 30.713800 4
B 29.186001 44.353699 9.057160 4
A 39.311199 27.371201 35.473999 5
B 31.437799 30.415001 37.454399 4
B 48.501999 1.277730 21.900600 4
...
数据由多个重复的数据块组成。每个数据块具有相同的格式如下:
First line = Number of lines of data block
Second line = ID of data block
From third line = Actual data lines (with number of lines designated in the first line)
例如,如果我们看到第一个数据块:
2 (=> This data block has 2 number of lines) 
1 (=> This data block's ID is 1 (very first data block))
A 11.364500 48.395199 40.160500 5
B 35.067699 30.944700 24.155300 4
(Third and fourth lines of the data block are actual data.
The integer of the first line, the number of lines for this data block, is 2, so the actual data consist of 2 lines.
All other data blocks follow the same format. )
  • 前两行是每个重复数据块的标题。第一行指定数据块的行数,第二行是数据块的ID。
  • 然后真实数据从每个数据块的第三行开始。正如我所解释的,“真实数据”的行数在第一行中指定为整数。
  • 因此,每个数据块的总行数将为number_of_lines+2。在这个例子中,数据块1的总行数为4,数据块2的总行数为6行...

  • 此格式重复 100,000 次。换句话说,我在单个文本文件中有 100,000 个数据块,就像这个例子一样。我可以提供数据块的总数。
    我希望做的是按第四列对每个数据块的“实际数据行”进行排序,并以与原始数据文件相同的格式打印出数据。我希望从上面的示例中实现的目标如下:
    2
    1
    A 11.364500 48.395199 40.160500 5
    B 35.067699 30.944700 24.155300 4
    4
    2
    A 26.274099 38.533298 32.624298 4
    A 15.850300 28.130899 24.753901 4
    A 32.098000 33.665699 20.372499 4
    B 36.459000 29.662701 17.806299 5
    5
    3
    B 1.326100 17.127600 39.600300 4
    B 35.853001 43.095901 17.402901 4
    B 31.686800 44.997501 16.619499 4
    A 9.837760 41.103199 13.062300 5
    A 17.501801 44.279202 8.005670 5
    3
    4
    B 31.274700 8.726580 25.267599 4
    A 19.032400 41.384701 19.456301 5
    B 19.441900 24.286400 6.961680 4
    1
    5
    B 48.973999 15.508400 5.099710 4
    6
    6
    B 31.437799 30.415001 37.454399 4
    A 39.311199 27.371201 35.473999 5
    B 30.145800 13.256200 30.713800 4
    A 42.586601 21.343800 23.280701 5
    B 48.501999 1.277730 21.900600 4
    B 29.186001 44.353699 9.057160 4
    ...
    我知道在 Linux 中使用第 4 列对数据进行排序的典型命令,即:
    sort -gk4 data.txt > data_4sort.txt
    但是,在这种情况下,我需要对每个数据块进行排序。另外,每个数据块没有统一的行数,但每个数据块的数据行数是不同的。
    我真的不知道我怎么能做到这一点。我正在考虑使用带有 for 循环和/或 awk、sed、split 等的 shell 脚本和 sort 命令。但我什至不确定如何使用 for 循环来解决这个问题,或者是否真的需要 for 循环和 shell 脚本来执行这种逐块排序。

    最佳答案

    使用 awk 准备用于排序的文本,然后将其通过管道传递给 sort 的 1 次调用,没有生成子shell,也没有创建临时文件:

    $ cat tst.sh
    #!/usr/bin/env bash

    awk '
    BEGIN { OFS="\t"; recNr=1 }
    NF < pNF { ++recNr }
    {
    print recNr, NF, NR, $0
    pNF = NF
    }
    ' "${@:--}" |
    sort -k1,1n -k2,2n -k7,7nr -k3,3n |
    cut -f4-
    $ ./tst.sh file
    2
    1
    A 11.364500 48.395199 40.160500 5
    B 35.067699 30.944700 24.155300 4
    4
    2
    A 26.274099 38.533298 32.624298 4
    A 15.850300 28.130899 24.753901 4
    A 32.098000 33.665699 20.372499 4
    B 36.459000 29.662701 17.806299 5
    5
    3
    B 1.326100 17.127600 39.600300 4
    B 35.853001 43.095901 17.402901 4
    B 31.686800 44.997501 16.619499 4
    A 9.837760 41.103199 13.062300 5
    A 17.501801 44.279202 8.005670 5
    3
    4
    B 31.274700 8.726580 25.267599 4
    A 19.032400 41.384701 19.456301 5
    B 19.441900 24.286400 6.961680 4
    1
    5
    B 48.973999 15.508400 5.099710 4
    6
    6
    B 31.437799 30.415001 37.454399 4
    A 39.311199 27.371201 35.473999 5
    B 30.145800 13.256200 30.713800 4
    A 42.586601 21.343800 23.280701 5
    B 48.501999 1.277730 21.900600 4
    B 29.186001 44.353699 9.057160 4
    这是上述 OPs 输入文件的执行速度的第三次运行时间差异:
    $ time ./tst.sh file >/dev/null

    real 0m0.105s
    user 0m0.030s
    sys 0m0.091s
    和当前的 awk 答案会为每个要排序的输入块生成一个子shell:
    @IceCreamTucan's answer :
    $ cat tst2.sh
    #!/usr/bin/env bash

    awk '{
    if(NF > 1){
    print | "sort -k4,4nr"
    }
    else{
    close("sort -k4,4nr")
    print
    }
    }' "${@:--}"
    $ time ./tst2.sh file >/dev/null

    real 0m0.405s
    user 0m0.120s
    sys 0m0.121s
    @paxdiablo's answer :
    $ cat tst3.sh
    #!/usr/bin/env bash

    awk '
    function sort() {
    close(tmp_file)
    system("sort -rnk4 "tmp_file"; rm -rf "tmp_file)
    }
    BEGIN { tmp_file = "/tmp/tmp_file" }
    state == 0 && NF == 1 { print ; next }
    state == 0 && NF != 1 { print >tmp_file ; state = 1 ; next }
    state == 1 && NF != 1 { print >>tmp_file ; next }
    state == 1 && NF == 1 { sort() ; print ; state = 0 ; next }
    END { if (state == 1) { sort() } }
    ' "${@:--}"
    $ time ./tst3.sh file >/dev/null

    real 0m0.804s
    user 0m0.060s
    sys 0m0.396s

    关于sorting - 连续排序重复数据但行数不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68416482/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com