用于查找包含 4 个或更多数字的行的 Unix 正则表达式 (ERE)

Unix Regex (ERE) for finding a lines with 4 or more numbers

我尝试了很多变体,但 none 似乎有效,我不知道我不明白什么。

我试过的最后一个是 (\<[[:digit:]]+\>.*){4,}。 但它甚至找不到像 123 123 123 123 这样的行。 输入行可以是任何东西(甚至像 hello 123 my 1 name 2 is 3)。

抱歉,我没有指定,但我的意思是:“123 a2”行有 1 个数字,“1 2 3 45”行有 4 个数字。

在您的 grep 命令中量化模式似乎存在一些问题。如果第一个数字有多个数字,而其他数字只包含一个数字,则您的正则表达式有效。否则,它不会,请参阅 testing results:

#!/bin/bash
s="123 1 2 3  - works, the first number is two+ digits, the rest are one digits
1 2 3 45 - does not work, the first number is one-digit
14 2 3 4 - works
123 a2 - not output as expected as there is just one number
12 and one 1 more and 23 and 6 and some more 3546
hello 123 my 1 name 2 is 3 - output fine since the first number is three-digit and the rest are one digit"
 
grep -E '(\<[[:digit:]]+\>.*){4,}' <<< "$s"

输出:

123 1 2 3  - works, the first number is two+ digits, the rest are one digits
14 2 3 4 - works
hello 123 my 1 name 2 is 3 - output fine since the first number is three-digit and the rest are one digit

如果你在没有 {4,} 的情况下重写它,它会起作用:

grep -E '\<[0-9]+\>.*\<[0-9]+\>.*\<[0-9]+\>.*\<[0-9]+\>' file

参见 this online demo

您也可以在任何环境中使用此 awk

awk '{cnt=0; for (i=1; i<=NF; ++i) { if ($i ~ /^[0-9]+$/) { cnt++ } } }cnt>3' file

online demo详情:

  • cnt=0 - 将 cnt 计数器变量设置为 0
  • for (i=1; i<=NF; ++i) {...} - 遍历当前记录中的所有字段(=行)
  • if ($i ~ /^[0-9]+$/) { cnt++ } } - 如果字段由数字组成递增 cnt
  • cnt>3 - 如果 cnt 大于 3,打印找到的记录。

参见 online demo:

#!/bin/bash
s="123  123  123  123 
1 2 3 45
1 3 5
hello 123 my 1 name 2 is 3" 

awk '{cnt=0; for (i=1; i<=NF; ++i) { if ($i ~ /^[0-9]+$/) { cnt++ } } }cnt>3' <<< "$s"

输出:

123  123  123  123 
1 2 3 45
hello 123 my 1 name 2 is 3

使用您显示的示例,请尝试以下 awk 代码。我们不需要在这里使用循环。此 awk 代码是在 GNU awk.

中编写和测试的
awk -v FPAT='(^|[[:space:]]+)[0-9]+([[:space:]]+|$)' 'NF>3' Input_file

解释:为以上添加详细解释。

  • 使用名为 FPAT 的 GNU awk 选项允许正则表达式制作字段分隔符。
  • 使用正则表达式 (^|[[:space:]]+)[0-9]+([[:space:]]+|$) 匹配起始空格后跟数字或数字后跟空格或行尾。
  • 在主要 awk 程序中检查条件 NF>3 这意味着如果字段数大于 3 则打印该行。