我有一个文件,其中包含如下所示的行
data
datalater
983290842
Data387428later
datafhj893724897290384later
4329804928later
我想要做的是使用正则表达式来匹配任何以数据开头并以后面结尾的行,并且两者之间有数字。这是我到目前为止所炮制的:
^[D,d]ata[0-9]*later$
但是,输出包括所有数据转换器行。我想我可以稍后管道输出和 grep -v 数据,但我觉得一个表达式应该可以解决问题。
使用+而不是*.
+至少匹配上述一项或多项。
*匹配零个或多个。
^[Dd]ata[0-9]+later$
在 grep 中,您需要转义+,我们可以使用\dwhich 是字符类并匹配单个数字。
^[Dd]ata\d\+later$
在您的示例文件中,您还有一行:
datafhj893724897290384later
由于数据和数字之间存在字母,因此目前不会匹配。我们可以通过添加一个[^0-9]*来匹配数据之后的任何内容直到数字来解决这个问题。
我们的最终命令将是:
grep '^[Dd]ata[^0-9]*\d\+later$' filename
您使用 * 限定符匹配零个或多个数字。尝试
^[Dd]ata\d+later$
反而。您还在字符串的开头找到逗号(例如“,ata1234later”)。\d 是查找任何数字字符的快捷方式。所以我也改变了这些。
您应该使用“+”(表示一个或多个)而不是“*”(表示零、一个或多个)
使用 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 恰当地指出了它的必要性。相反,我使用.*which 匹配任何不匹配模式下一部分的字符序列。这是我的命令和输出。
$ 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
$
“+”语法仅适用于扩展正则表达式,不适用于标准 grep。
至少,这是我在 RHEL 上的经验。
要使用扩展正则表达式,请运行 egrep 或通过 "-E" / "--extended-regexp" 示例...
标准 grep
echo abc123n1 | grep "abc[0-9]+n1"
<no output>
鹭鸶
echo abc123n1 | egrep "abc[0-9]+n1"
abc123n1
grep 与 -E
echo abc123n1 | grep -E "abc[0-9]+n1"
abc123n1
HTH
动机
其余答案不适用于所有系统。
️ 要求
命令
grep --extended-regexp "[[:group:]]+"
️ 组