【问题标题】:How to do a pattern range match that is multi-line and non-greedy?如何进行多行且非贪婪的模式范围匹配?
【发布时间】:2013-12-28 10:18:24
【问题描述】:

我正在尝试使用 bash 单线在两个图案之间打印线条。不过,我需要它是非贪婪的。我有一个包含以下内容的文件“test.txt”:

############ Apple ############
# 1
# 2
# 3
# 4      
#################################

############ Orange ############
# 1
# 2
# 3
# 4
#################################

############ Grape ############
# 1
# 2
# 3
# 4      
#################################

我想要打印的是“橙色”部分。只有那个部分。也就是说,我要打印以下内容:

############ Orange ############
# 1
# 2
# 3
# 4
#################################

我也不想匹配特定数量的行,因为行数会波动。我尝试了很多不同的东西。我尝试过 sed、awk、grep(使用 -P 和 *.? 正则表达式)。这里似乎没有什么适合的。 sed 和 awk 是贪心的,所以我无法匹配部分的结尾。 Grep(据我所知)不支持多行范围匹配。有没有使用内置的解决方案?我知道有 pcregrep,但我宁愿使用内置插件或与常见发行版一起“发布”的东西。我要“开箱即用”和优雅。有可能吗?

【问题讨论】:

    标签: regex bash


    【解决方案1】:

    使用 的地址范围:

    sed -n '/^#\+[ ]*Orange[ ]*#\+/,/^#\+$/ p' infile
    

    它产生:

    ############ Orange ############
    # 1
    # 2
    # 3
    # 4
    #################################
    

    【讨论】:

    • 谢谢。将您的答案修改为:sed -n '/orange/I,/##/p'
    【解决方案2】:
    perl -ne 'BEGIN{$/=/^#+$/} print $_ if /Orange/' file
    

    【讨论】:

    • 这行得通,但我最终这样做了:sed -n '/orange/I,/##/p'
    猜你喜欢
    • 1970-01-01
    • 2011-03-02
    • 2014-07-06
    • 2012-11-17
    • 2015-01-03
    • 1970-01-01
    • 2013-06-09
    • 1970-01-01
    相关资源
    最近更新 更多