grep 可变长度可选文本

grep 可变长度可选文本

我想搜索具有前面可选文本块的边缘锚定文本,其中任意数量的文本都可以包含在匹配中。例如,假设我正在尝试查找^xyz但也会接受^wxyz, ^vwxyz, ^uvwxyz, ^tuvwxyz, ^stuvwxyz, ^rstuvwxyz, 但是没有其他可能性(对于我的实际搜索,我不能简单地使用正则表达式字符序列,[r-w]因为前面的字符的实际块并不像这个简化示例中那样按字母顺序排列),我可以使用命令egrep '^r?s?t?u?v?w?xyz'.是否有另一种方法来编写此搜索,以便我可以简单地将可选标志 ( ?) 应用于整个序列而不是单独应用于每个元素?

编辑:

下面是一个更真实的数据示例:要匹配的全文是 AZHDEOIMOSJDJKEJLCN。然而,字母从左端不同程度地丢失,因此以下所有内容都应该匹配:

^AZHDEOIMOSJDJKEJLCN
^ZHDEOIMOSJDJKEJLCN
^HDEOIMOSJDJKEJLCN
^DEOIMOSJDJKEJLCN
^EOIMOSJDJKEJLCN
^OIMOSJDJKEJLCN
^IMOSJDJKEJLCN
^MOSJDJKEJLCN
^OSJDJKEJLCN
^SJDJKEJLCN
^JDJKEJLCN
^DJKEJLCN
^JKEJLCN
^KEJLCN

因此,残差KEJLCN是必需的,而其之前的所有内容都是可选的。但是,我不能简单地使用grepfor,KEJLCN因为我只想要锚定到行开头 ( ^) 的实例,并且可以选择在上面列出的其他字符前面。另请注意,搜索字符串将位于变量中,并且最小残基(例如KEJLCN)将通过脚本中的子字符串操作提取(例如,在 perl 环境中,egrep作为搜索文本的系统命令运行$query,基本文本将包含在) 中substr($query,-6),可选的前面文本将包含在substr($query,0,length($query)-6) 中。因此,该解决方案应该对变量形式的正则表达式有效,而不仅仅是字符串文字。

答案1

grep '[[:lower:]]*xyz'

将返回与该模式匹配的所有行。但是,当然,这与显式的字符序列不匹配。

不过,这似乎是您已经解决的问题:

grep -f - <<\STRINGS /dev/fd/3 3<<\DATA
^ZHDEOIMOSJDJKEJLCN
^HDEOIMOSJDJKEJLCN
^DEOIMOSJDJKEJLCN
^EOIMOSJDJKEJLCN
^OIMOSJDJKEJLCN
^IMOSJDJKEJLCN
^MOSJDJKEJLCN
^OSJDJKEJLCN
^SJDJKEJLCN
^JDJKEJLCN
^DJKEJLCN
^JKEJLCN
^KEJLCN
STRINGS

SJDJKEJLCN                                                                  
JDJKEJLCN
o;aidsfjoasjif
KKEJnotLCN
DATA

输出

SJDJKEJLCN                                                                 
JDJKEJLCN 

如果您想以编程方式生成相同的查找表......

grep -f - <<STRINGS /dev/fd/3 3<<\DATA
$(
    MATCH=ZHDEOIMOSJDJKEJLCN
    until [ ${#MATCH} -lt ${MINLEN=6} ]
    do  printf '^%s\n' "$MATCH"
        MATCH=${MATCH#?}
    done
)
STRINGS

SJDJKEJLCN                                                                  
JDJKEJLCN                                                                  
o;aidsfjoasjif                                                             
KKEJnotLCN                                                                 
DATA

输出

SJDJKEJLCN                                                                  
JDJKEJLCN

相关内容