如何使用 Bash 从 grep 搜索模式中收集最大值和最小值?



我有一个巨大的日志.txt文件,我需要从中计算最大值和最小值。

0-00:42:35.598 <tc_testcase>:[DEFAULT]:[PRINT]: tc_testcase.c:8963: VERIFY_CASE: range: X_PER_Y_USER_RANGE_0[1](a, 1)=121, (0)=0, (25000)=25000, (ok)
0-00:42:35.598 <tc_testcase>:[DEFAULT]:[PRINT]: tc_testcase.c:8963: VERIFY_CASE: range: X_PER_Y_USER_RANGE_0[1](a, 1)=256879, (0)=0, (25000)=25000, (ok)
0-00:42:35.598 <tc_testcase>:[DEFAULT]:[PRINT]: tc_testcase.c:8963: VERIFY_CASE: range: X_PER_Y_USER_RANGE_0[1](a, 1)=2300, (0)=0, (25000)=25000, (ok)
0-00:42:35.598 <tc_testcase>:[DEFAULT]:[PRINT]: tc_testcase.c:8963: VERIFY_CASE: range: X_PER_Y_USER_RANGE_0[1](a, 1)=56897132, (0)=0, (25000)=25000, (ok)
0-00:42:35.598 <tc_testcase>:[DEFAULT]:[PRINT]: tc_testcase.c:8963: VERIFY_CASE: range: X_PER_Y_USER_RANGE_0[1](a, 1)=12579, (0)=0, (25000)=25000, (ok)
0-00:42:35.598 <tc_testcase>:[DEFAULT]:[PRINT]: tc_testcase.c:8963: VERIFY_CASE: range: X_PER_Y_USER_RANGE_0[1](a, 1)=968746, (0)=0, (25000)=25000, (ok)

因此,作为第一步,我开始使用下面的 grep 命令将以下行收集到一个单独的文件中,然后对其进行排序:

grep -Po '.X_PER_Y_USER_RANGE_0.*[1].*(a, 1).K.*' file.txt > collect.txt

但是我收到的输出完全不同。它看起来像这样:-

=121, (25000)=25000, (ok)
=256879, (25000)=25000, (ok)
=2300, (25000)=25000, (ok)
=56897132, (25000)=25000, (ok)
=12579, (25000)=25000, (ok)
=968746, (25000)=25000, (ok)

预期应该是:-

121
256879
2300
56897132
12579
968746

任何人都可以帮助修改我用来收集值作为预期输出的当前 grep 命令

你很接近,试图在这里修复 OP 的尝试。这可以在 GNU 中完成grep如下所示。我们可以使用 GNUgrep-P选项在那里启用 PCRE 正则表达式。

grep -oP '.*range: X_PER_Y_USER_RANGE_0[1]([a-zA-Z]+, d+)=Kd+'  Input_file

解释:简单的解释是,首先为 GNU 启用-oP选项grep以启用 PCRE 正则表达式功能并仅获取匹配的值。然后在 grep 的主程序中,使用正则表达式.*range: X_PER_Y_USER_RANGE_0[1]([a-zA-Z]+, d+)=来匹配从开始到 () 的所有内容,注意这里转义了[]()的一部分,使这些字符成为文字字符。然后使用K选项忘记所有匹配的值,直到现在。提及d+将匹配它后面的数字,这是OP获取数字的实际要求。

你只需要转义特殊的正则表达式字符:

grep -Po 'range: X_PER_Y_USER_RANGE_0[1](a, d)=Kd+' file.txt
121
256879
2300
56897132
12579
968746

对于这种情况(对我来说),Perl本身更可取:

perl -lne '/ d)=Kd+/ && print $&' file.txt
121
256879
2300
56897132
12579
968746

对于最小最大,如下所示:

perl -lne '/ d)=Kd+/g && push(@number,$&); END{ print "@{[sort {$a <=> $b} @number]}[0,-1]"}' file.txt
121 56897132

END { ... }表示对它们进行排序并取出0last@number数组的索引

对于使用 bash 而不是Perl进行最小值和最大值sort,您可以将输出通过管道传输到:

... | { mapfile -t arr; paste <(sort -n <(tr ' ' 'n' <<<  ${arr[@]})) <(sort -rn <(tr ' ' 'n' <<<  ${arr[@]})); }
121 56897132
2300    968746
12579   256879
256879  12579
968746  2300
56897132    121

这将创建一个数组,然后sort两次。然后只需通过管道将其传输到head -n 1

例如
... | head -n 1
121 56897132

最新更新