获取日志中第一次出现的组

获取日志中第一次出现的组

我有一个巨大的日志,我打算仅过滤每个组的第一次出现。在日志中,“组”是第一列中时间戳之后的所有内容。

看一个例子:

Mar 06 16:34:00.378;sample07;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:02.856;sample03;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;
Mar 06 16:34:03.314;sample07;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:03.525;sample07;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:04.773;sample01;0.1.0-3af8c384;A6OZwO2e9wV6Z1PI;
Mar 06 16:34:04.997;sample04;0.1.0-3af8c384;9azoPOnrcabk8Lfv;
Mar 06 16:34:05.241;sample04;0.1.0-3af8c384;9azoPOnrcabk8Lfv;
Mar 06 16:34:06.546;sample04;0.1.0-3af8c384;9azoPOnrcabk8Lfv;
Mar 06 16:34:06.671;sample08;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:07.394;sample05;0.1.0-3af8c384;JJYhwRHyTMNKM2DI;
Mar 06 16:34:07.569;sample05;0.1.0-3af8c384;JJYhwRHyTMNKM2DI;
Mar 06 16:34:09.120;sample05;0.1.0-3af8c384;JJYhwRHyTMNKM2DI;
Mar 06 16:34:09.371;sample05;0.1.0-3af8c384;JJYhwRHyTMNKM2DI;
Mar 06 16:34:09.534;sample06;0.1.0-3af8c384;tasghviiAoMrPfaZ;
Mar 06 16:34:09.662;sample04;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;
Mar 06 16:34:09.822;sample07;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;

预期结果是:

Mar 06 16:34:00.378;sample07;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:02.856;sample03;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;
Mar 06 16:34:04.773;sample01;0.1.0-3af8c384;A6OZwO2e9wV6Z1PI;
Mar 06 16:34:04.997;sample04;0.1.0-3af8c384;9azoPOnrcabk8Lfv;
Mar 06 16:34:06.671;sample08;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:07.394;sample05;0.1.0-3af8c384;JJYhwRHyTMNKM2DI;
Mar 06 16:34:09.534;sample06;0.1.0-3af8c384;tasghviiAoMrPfaZ;
Mar 06 16:34:09.662;sample04;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;

我能够得到没有时间戳的独特组合:

cut -d";" -f2- small_log.log | sort | uniq

但我如何将其连接回来以获得时间戳呢?我也不认为这sort | uniq能很好地扩展到数百万行。

答案1

我会在 awk 中这样做:

$ awk -F';' '++seen[$2$3$4]==1' file 
Mar 06 16:34:00.378;sample07;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:02.856;sample03;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;
Mar 06 16:34:04.773;sample01;0.1.0-3af8c384;A6OZwO2e9wV6Z1PI;
Mar 06 16:34:04.997;sample04;0.1.0-3af8c384;9azoPOnrcabk8Lfv;
Mar 06 16:34:06.671;sample08;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:07.394;sample05;0.1.0-3af8c384;JJYhwRHyTMNKM2DI;
Mar 06 16:34:09.534;sample06;0.1.0-3af8c384;tasghviiAoMrPfaZ;
Mar 06 16:34:09.662;sample04;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;

当某项计算结果为 true 时的默认操作awk是打印当前行。该表达式++seen[$1$2}使第二个和第三个字段成为关联数组中的键seen,并将其值加一。因此,++seen[$2$3$4]==1仅在第一次看到第二场和第三场的组合时才成立。

它基本上是一种简写方式:

awk -F';' '{ 
             seen[$2$3$4]++; 
             if(seen[$2$3$4] == 1){
                print
             }
            }' file 

或者,您也可以像您尝试的那样使用sort.您甚至不需要cut,只需告诉sort对字段 2 到 4 进行排序并返回唯一的结果:

$ sort -t';' -k2,4 -u file 
Mar 06 16:34:04.773;sample01;0.1.0-3af8c384;A6OZwO2e9wV6Z1PI;
Mar 06 16:34:02.856;sample03;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;
Mar 06 16:34:04.997;sample04;0.1.0-3af8c384;9azoPOnrcabk8Lfv;
Mar 06 16:34:09.662;sample04;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;
Mar 06 16:34:07.394;sample05;0.1.0-3af8c384;JJYhwRHyTMNKM2DI;
Mar 06 16:34:09.534;sample06;0.1.0-3af8c384;tasghviiAoMrPfaZ;
Mar 06 16:34:00.378;sample07;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:06.671;sample08;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;

如果您需要按时间戳对它们进行排序,只需sort再次通过管道:

$ sort -t';' -k2,4 -u file  | sort
Mar 06 16:34:00.378;sample07;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:02.856;sample03;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;
Mar 06 16:34:04.773;sample01;0.1.0-3af8c384;A6OZwO2e9wV6Z1PI;
Mar 06 16:34:04.997;sample04;0.1.0-3af8c384;9azoPOnrcabk8Lfv;
Mar 06 16:34:06.671;sample08;0.1.0-3af8c384;WXHXdaYrHcVQYvLR;
Mar 06 16:34:07.394;sample05;0.1.0-3af8c384;JJYhwRHyTMNKM2DI;
Mar 06 16:34:09.534;sample06;0.1.0-3af8c384;tasghviiAoMrPfaZ;
Mar 06 16:34:09.662;sample04;0.1.0-3af8c384;Y2XdtYN2of7JUc4b;

相关内容