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



我有这个:

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

这就给出了:

1234
5

我知道发生了什么。如何阻止grep在1次成功匹配后继续匹配?

如何只获得

1234

您是希望grep停止匹配,还是只关心第一个匹配。如果后者为真,则可以使用head。。。

`grep stuff | head -n 1` 

Grep是一个基于行的util,因此-m 1标志告诉Grep在匹配第一个后停止,当与head组合时,这在实践中非常好。

您需要进行分组:(...)然后是确切的出现次数:{<n>}才能完成任务:

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

希望能有所帮助。干杯

使用sed而不是grep:

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

这在行首最多匹配4位数字,后面跟着任何数字,只保留数字并打印它们。-n可防止以其他方式打印行。如果数字字符串也可能出现在中间,那么您需要一个稍微复杂一点的命令。

事实上,理想情况下,您将使用带有PCRE正则表达式的sed,因为您确实需要非贪婪匹配。然而,在合理的近似值范围内,您可以使用:一个相当复杂的问题的半解决方案…现已删除!

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

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

这将匹配一个由1-4位数字和任意数字组成的字符串,只保留数字并打印它们。

如果像您的示例一样,您的数字表达式将出现在您开始使用的字符串的开头,那么您只需添加一个线锚^:的开头

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

根据您需要的确切数字,线尾锚$可能也会有所帮助。

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)上测试了它,它成功了!

最新更新