使用grep只匹配一行中的模式一次

时间:2012-03-03 03:37:04

标签: regex linux bash grep

我有这个:

 echo 12345 | grep -o '[[:digit:]]\{1,4\}'

这给出了这个:

1234
5

我明白发生了什么事。如何在成功匹配后阻止grep尝试继续匹配?

我如何才能获得

1234

5 个答案:

答案 0 :(得分:8)

你想要grep停止匹配还是只关心第一场比赛。如果后者属实,您可以使用head

`grep stuff | head -n 1` 

Grep是一个基于行的util,所以-m 1标志告诉grep在匹配第一个之后停止,当与head结合时,它实际上非常好。

答案 1 :(得分:5)

您需要进行分组:\(...\)后跟确切的出现次数:\{<n>\}来完成工作:

maci:~ san$ echo 12345 | grep -o '\([[:digit:]]\)\{4\}'
1234

希望它有所帮助。干杯!!

答案 2 :(得分:3)

使用sed代替grep

echo 12345 | sed -n '/^\([0-9]\{1,4\}\).*/s//\1/p'

在行的开头匹配最多4位数字,后跟任何内容,只保留数字,然后打印它们。 -n会阻止打印行。如果数字字符串也可能出现在中间位置,则需要稍微复杂的命令。

事实上,理想情况下,你会使用sed和PCRE正则表达式,因为你真的需要一个非贪婪的匹配。但是,在合理的近似值下,您可以使用:对一个相当复杂的问题的半解决方案......现已删除了!

由于您需要第一个最多4位数的字符串,只需使用sed删除任何非数字,然后打印数字字符串:

echo abc12345 | sed -n '/^[^0-9]*\([0-9]\{1,4\}\).*/s//\1/p'

这匹配一串非数字后跟1-4位数字后跟任何内容,只保留数字,并打印出来。

答案 3 :(得分:0)

如果 - 在您的示例中 - 您的数字表达式将出现在您开始使用的字符串的开头,则只需添加一个行首锚select datediff (SECOND,start, stop) from test

select 1 
where ((select datediff (SECOND,start, stop) from test) > 5)

根据您想要的确切数字,行尾锚^也可能有所帮助。

答案 4 :(得分:0)

grep手册页对此主题进行了说明(请参见“正则表达式”一章):

 (…)

 {n,}

      The preceding item is matched n or more times. 

 {n,m}     

      The preceding item is matched at least n times, but not more than m times. 

 (…)

所以答案应该是:

 echo 12345 | grep -o '[[:digit:]]\{4\}'

我刚刚在cygwin终端(2018)上对其进行了测试,并且有效!