【问题标题】:Remove all lines between two strings删除两个字符串之间的所有行
【发布时间】:2011-01-09 08:32:30
【问题描述】:

在 sh shell 脚本中。

给定文本文件中的数据:

string1  
string2 gibberish  
gibberish  
string3 gibberish  
string4  

如何使用 awk 或 sed 删除string2(包括)和string3(不包括string3)之间的所有行?

结束于:

string1  
string3  
string4  

【问题讨论】:

  • 嘿,如果您要删除 both string2 和 string3 以及介于两者之间的所有内容,那么在 sed 中很容易:/string2/,/string3/d

标签: string sed awk


【解决方案1】:

以下将在 sed

中工作
sed  '
/string2/,/string3/bdeleting
b
:deleting
s/string3.*/string3/
/string3/b
d
'

假设我们匹配到 string2

之后第一次出现的 string3

【讨论】:

    【解决方案2】:

    你可以试试这个。 "string2" 之前的任何内容都不会被删除。

    awk 'BEGIN{f=0}
    {
        match($0,"string2")
        if(RSTART){
            print substr($0,1,RSTART-1)
            f=1
            next
        }
        match($0,"string3")
        if(RSTART){
            $0=substr($0,RSTART)
            f=0
        }
    }
    f==0{print}
    ' file
    

    输出

    $ cat file
    string1 blah blah
    text before string2 junk
    gibberish
    gibberis string3 text here
    string4
    
    $ ./shell.sh
    string1 blah blah
    text before
    string3 text here
    string4
    

    【讨论】:

    • 这是一个适用于我的综合解决方案。谢谢!
    【解决方案3】:

    string1、string2、string3 等是否在不同的行上? 在这种情况下,您可以使用 awk:

    awk '/string2/{flag=1} /string3/{flag=0} !flag'
    

    或sed:

    sed '/string3/p; /string2/,/string3/d'
    

    【讨论】:

    • 这太棒了。 sed 和 awk 语法从不让我坚持,所以每次看到这样的东西我都把它比作魔术。
    • 这些字符串在不同的行上。每个字符串后面都有另一个词是动态的。
    • 如果他们自己在线,这些完全有效。但是,在您询问后不久,我意识到在同一行上的字符串之前或之后有一些不需要删除的单词。
    • 上述 sed 解决方案会不会导致“string3”行加倍而不是“string2”行?
    • 你是对的,但考虑到 OP 的问题,我假设输入文件总是在包含“string3”的行之前包含包含“string2”的行
    【解决方案4】:

    这是一个示例正则表达式替换:

    s/string2.*?(?=string3)//sg
    

    这将删除从 string2 到但不包括 string3 的所有内容。

    【讨论】:

    • 我想那是 Perl,对吧?因为对我来说,它看起来不像“awk 或 sed”(如问题所述)。 :-P
    • 是的,sed 也不是非贪婪的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-06
    • 2016-07-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 2021-04-02
    相关资源
    最近更新 更多