gpt4 book ai didi

bash - 使用 GREP 对数据进行子集化

转载 作者:行者123 更新时间:2023-11-29 09:25:27 26 4
gpt4 key购买 nike

我有一个非常大的文本文件 (16GB),我想尽快对其进行子集化。这是所涉及数据的示例

0   M   4   0   
0 0 Q 0 10047345 3080290,4098689 50504886,4217515 9848058,1084315 50534229,4217515 50591618,4217515 26242582,2597528 34623075,3279130 68893581,5149883 50628761,4217517 32262001,3142702 35443881,3339757
0 108 C 0 50628761
0 1080 C 0 50628761
1 M 7 0
1 0 Q 0 17143989
2 M 15 1
2 0 Q 0 17143989 4219157,1841361,853923,1720163,1912374,1755325,4454730 65548702,4975721 197782,39086 54375043,4396765 31589696,3091097 6876504,851594 3374640,455375 13274885,1354902 31585771,3091016 61234218,4723345 31583582,3091014
2 27 C 0 31589696

每行的第一个数字是 sessionID,任何带有“M”的行都表示 session 的开始(数据按 session 分组)。 M 后面的数字是 Day,第二个数字是 userID,一个用户可以有多个 session 。

我想提取与特定用户相关的所有行,每个 session 包括所有行,直到遇到下一个“M”行(可以是任意数量的行)。作为第二个任务,我还想提取与特定日期相关的所有 session 行。

例如,对于上述数据,要提取用户 ID“0”的记录,输出将是:

0   M   4   0   
0 0 Q 0 10047345 3080290,4098689 50504886,4217515 9848058,1084315 50534229,4217515 50591618,4217515 26242582,2597528 34623075,3279130 68893581,5149883 50628761,4217517 32262001,3142702 35443881,3339757
0 108 C 0 50628761
0 1080 C 0 50628761
1 M 7 0
1 0 Q 0 17143989

要提取第 7 天的记录,输出将是:

1   M   7   0
1 0 Q 0 17143989

我相信对于我目前所取得的成就,有一个更优雅、更简单的解决方案,如果能得到一些反馈和建议,那就太好了。谢谢。

我尝试过的

我尝试使用 pcrgrep -M 直接应用此模式(匹配两个 M 之间的数据),但很难让它在换行符上正常工作。我仍然怀疑这可能是最快的选择,因此任何关于这是否可能的指导都会很好。

下一部分比较零散,如果您已经有了更好的解决方案,则无需继续阅读!

如果无法满足上述要求,我将问题分为两部分:

  • 第 1 部分:隔离所有“M”行以获得属于该用户/天的 session 列表

    1. grep 方法很快(然后需要弄清楚如何使用这些数据)

      时间 grep -c "M\t.*\t$user_id"trainSample.txt >> sessions.txt

    2. awk 方法创建数组很慢

      time myarr=$(awk '/M\t.*\t$user_id/{print $1}' trainSample.txt

  • 第 2 部分:在第 1 部分中创建的列表中提取属于某个 session 的所有行

    1. 继续 awk 方法,我为每个方法都运行了 grep,但这太慢了(完成 16GB 需要几天时间)

      for i in "${!myarr[@]}"; 
      do
      grep "^${myarr[$i]}\t" trainSample.txt >> sessions.txt
      echo -ne "Session $i\r"
      done
    2. 与其像上面那样为每个 session ID 运行一次 grep,不如在一个 grep 命令中全部使用它们要快得多(我使用 [1|2|3|.​​.|8] 格式的 8 个 session ID 运行它,并且它花费的时间与每个人分别花费的时间相同,即快 8 倍)。但是我需要弄清楚如何动态地执行此操作

更新

我实际上已经建立了一个只需几秒钟即可完成的工作解决方案,但它是一些困惑且不灵活的 bash coe,我还没有扩展到第二种情况(按天隔离)。

最佳答案

I want to extract all lines related to a specific user which for each session include all of the lines up until the next 'M' line is encountered (can be any number of lines).

$ awk '$2=="M"{p=$4==0}p' file
0 M 4 0
0 0 Q 0 10047345 3080290,4098689 50504886,4217515 9848058,1084315 50534229,4217515 50591618,4217515 26242582,2597528 34623075,3279130 68893581,5149883 50628761,4217517 32262001,3142702 35443881,3339757
0 108 C 0 50628761
0 1080 C 0 50628761
1 M 7 0
1 0 Q 0 17143989

As a second task I also want to extract all session lines related to a specific day.

$ awk '$2=="M"{p=$3==7}p' file
1 M 7 0
1 0 Q 0 17143989

关于bash - 使用 GREP 对数据进行子集化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39847267/

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