【问题标题】:Grep: begin with string1, end with first occurence of string2grep:以 string1 开始,以 string2 的第一次出现结束
【发布时间】:2014-03-23 15:50:46
【问题描述】:

我正在尝试解析一个包含多个 http 链接的 HTML 文件。 我想得到一个以特定字符串开头并以另一个特定字符串结尾的 BIG 行,但我不知道这两个字符串之间是什么,所以这是我的问题:如果我像这样使用 grep:

grep -E -o 'string1.+string2'

我得到一条对应于正则表达式的大线,但它以最后一次出现的“string2”结束,因为“.+”。 实际上,我希望它在第一次出现“string2”时结束,所以我尝试了:

grep -E -o 'string1[^(string2)]+string2'

但它也不起作用,我得到相同的结果:( ...

如何告诉 grep 匹配以 'string1' 开始并以 'string2' 的第一次出现结束的行?

感谢您阅读我的文章

【问题讨论】:

    标签: bash grep


    【解决方案1】:

    + 操作符正在“贪婪”地吃掉它可以吃掉的所有字符(包括string2)。您可以通过添加? 使其不贪心(仅在启用perl 匹配时才支持,因此-P 标志):

    grep -P -o 'string1.+?string2
    

    【讨论】:

    • 我可能是错的,但我阅读 OP 问题的方式我认为您需要将其锚定在 ^ 上。
    • 它工作得很好!非常感谢mych,我一直在尝试无数种方法......其实很简单^^
    • @kojiro OP 有-o 标志,因此它只会输出匹配的那部分行。
    • @PlasmaPower 与是否锚定无关。我的意思是它可以匹配 string1 不在行首的行。
    • @kojiro 是的,但只会输出想要的部分。 @user3451029 你想让它匹配类似于blah string1 blah string2 的行吗?
    【解决方案2】:

    有些过于复杂awks

    cat file
    this is a test string1 get this data string2 but not this string2 end here
    

    awk -F"string" '{split($3,a," ");print FS $2 FS a[1]}' file
    string1 get this data string2
    

    awk '{for (i=1;i<=NF;i++) {if ($i=="string1") f=1;if (f) printf $i FS; if ($i=="string2") f=0}print ""}' file
    string1 get this data string2
    

    很高兴看到一个更简单的版本:)

    【讨论】:

    • 过于复杂的awks 总是很有趣! :) 在这种情况下,正则表达式可能是要走的路。此外,这将在末尾打印一个额外的字段分隔符。
    猜你喜欢
    • 2013-12-02
    • 2018-07-02
    • 1970-01-01
    • 2018-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-26
    相关资源
    最近更新 更多