正则表达式不检查文本的某些部分

时间:2018-01-23 08:21:57

标签: regex linux syntax grep

我的示例文件包含要通过egrep命令分析的数据:

[IG#]
IG#
[RM#]
RM#
[IG#1234]
[IG# 1234]
[IG #1234] [RM# ]
[IG# 1234] [RM #1224]
[RM#1234]
[RM# 1234]
[RM #1234]
[RM# 1234] [IG#]
[RM# ] [IG#1234]
#1234
1234

我的正则表达式看起来:

(RM#.*[0-9]|IG#.*[0-9]|\b([A-Z][A-Z0-9]+-[0-9]+)\b)

我不想只找到[RM#{digits}]和[IG#{digits}]的行,但它会像使用OR一样返回,结果如下:

[IG#1234]
[IG# 1234]
[IG# 1234] [RM #1224]
[RM#1234]
[RM# 1234]
[RM# 1234] [IG#]
[RM# ] [IG#1234]

预期输出

[IG# 1234]
[RM# 1234]
[IG# 1234] [RM1224]

2 个答案:

答案 0 :(得分:1)

看起来你想搜索一条应该按任意顺序匹配两个不同字符串的行。一种方法可以做到这一点

$ grep -E 'RM\s*#\s*[0-9]' ip.txt | grep -E 'IG\s*#\s*[0-9]'
[IG# 1234] [RM #1224]
  • \s将匹配任何空格字符,如果足够则使用文字空间
  • 添加其他约束,例如在需要时检查[]周围的RM/IG


要一次性检查,需要创建所有排列

$ grep -E 'RM\s*#\s*[0-9].*IG\s*#\s*[0-9]|IG\s*#\s*[0-9].*RM\s*#\s*[0-9]' ip.txt
[IG# 1234] [RM #1224]

$ # awk is better suited
$ awk '/RM\s*#\s*[0-9]/ && /IG\s*#\s*[0-9]/' ip.txt
[IG# 1234] [RM #1224]

答案 1 :(得分:1)

|是"替代",即它实际上意味着OR。正则表达式中没有AND - 要么枚举可能性

egrep 'RM ?# ?[0-9].*IG ?# ?[0-9]|IG ?# ?[0-9].*RM ?# ?[0-9]'

或使用两个greps

 egrep 'RM ?# ?[0-9]' file | egrep 'IG ?# ?[0-9]'