使用grep regex匹配任意位数

时间:2013-02-17 21:35:48

标签: regex grep

我有一个文件,其中的行看起来类似如下

data
datalater
983290842
Data387428later
datafhj893724897290384later
4329804928later

我要做的是使用正则表达式来匹配任何以数据开头并以后结束的行,并在其间包含数字。这是我到目前为止所编造的内容:

^[D,d]ata[0-9]*later$ 

但输出包括所有数据行。我想我可以管道输出和grep -v datalater,但我觉得单个表达式应该可以解决问题。

5 个答案:

答案 0 :(得分:3)

使用+代替*

+至少匹配前面的一个或多个。
*匹配零或更多。

^[Dd]ata[0-9]+later$

在grep中你需要转义+,我们可以使用\d这是一个字符类并匹配单个数字。

^[Dd]ata\d\+later$

在您的示例文件中,您还有一行:

datafhj893724897290384later

由于数据和数字之间存在字母,因此目前无法匹配。我们可以通过添加[^0-9]*以匹配数据之后的任何内容直到数字来解决此问题。

我们的最终命令是:

grep '^[Dd]ata[^0-9]*\d\+later$' filename

答案 1 :(得分:2)

您使用*限定符匹配零个或多个数字。尝试

^[Dd]ata\d+later$

代替。你也在字符串的开头找到逗号(例如“,ata1234later”)。而\ d是查找任何数字字符的快捷方式。所以我也改变了。

答案 2 :(得分:1)

你应该加一个“+”(意思是一个或几个)而不是“*”(这意味着零,一个或几个

答案 3 :(得分:0)

使用Cygwin,上述命令不起作用。我不得不修改上面给出的命令以获得所需的结果。

$ cat > file.txt <<EOL
> data
> datalater
> 983290842
> Data387428later
> datafhj893724897290384later
> 4329804928later
> EOL

我总是希望确保我的文件符合我的预期:

$ cat file.txt
data
datalater
983290842
Data387428later
datafhj893724897290384later
4329804928later

$

我需要使用-P标志运行Perl样式的表达式。这意味着我无法使用[^0-9]+,其必要性@Tom_Cammann恰当地指出。相反,我使用.*匹配任何与模式的下一部分不匹配的字符序列。这是我的命令和输出。

$ grep -P '^[Dd]ata.*\d+later$' file.txt
Data387428later
datafhj893724897290384later

$

我希望我能更好地解释为何需要Perl表达式,但我只知道Cygwin的grep的工作方式有点不同。

系统信息

$ uname -a
CYGWIN_NT-10.0 A-1052207 2.5.2(0.297/5/3) 2016-06-23 14:29 x86_64 Cygwin

我之前回答的结果

$ grep '^[Dd]ata[^0-9]*\d\+later$' file2.txt

$ grep '^[Dd]ata\d+later$' file2.txt

$ grep -P '^[Dd]ata[^0-9]*\d\+later$' file2.txt

$ grep -P '^[Dd]ata\d+later$' file2.txt
Data387428later

$

答案 4 :(得分:0)

“ +”语法仅适用于扩展的正则表达式,不适用于标准grep。
至少,这就是我在RHEL上的经验。

要使用Extended-regexp,请运行egrep或传递“ -E” /“-extended-regexp” 例子...

标准grep

echo abc123n1  | grep "abc[0-9]+n1"
<no output>

egrep

echo abc123n1  | egrep "abc[0-9]+n1"
abc123n1

grep -E

echo abc123n1  | grep -E "abc[0-9]+n1"
abc123n1

HTH