How do I delete a matching line and the previous one?

前端 未结 4 896
说谎
说谎 2020-12-11 05:13

I need delete a matching line and one previous to it. e.g In file below I need to remove lines 1 & 2.

I tried \"grep -v -B 1 \"page.of.\" 1.txt and I

相关标签:
4条回答
  • 2020-12-11 05:39
    grep -vf <(grep -B1 "page.*of" file | sed '/^--$/d') file
    
    0 讨论(0)
  • 2020-12-11 05:42

    You want to do something very similar to the answer given

    sed -n '
    /page . of ./ { #when pattern matches
    n #read the next line into the pattern space
    x #exchange the pattern and hold space
    d #skip the current contents of the pattern space (previous line)
    }
    
    x  #for each line, exchange the pattern and hold space
    1d #skip the first line
    p  #and print the contents of pattern space (previous line)
    
    $ { #on the last line
    x #exchange pattern and hold, pattern now contains last line read
    p #and print that
    }'
    

    And as a single line

    sed -n '/page . of ./{n;x;d;};x;1d;p;${x;p;}' 1.txt
    
    0 讨论(0)
  • 2020-12-11 05:47

    Not too familiar with sed, but here's a perl expression to do the trick:

    cat FILE | perl -e '@a = <STDIN>;
                        for( $i=0 ; $i <= $#a ; $i++ ) { 
                         if($i > 0 && $a[$i] =~ /xxxx/) { 
                           $a[$i] = ""; 
                           $a[$i-1] = "";
                         }
                        } print @a;'
    

    edit:

    where "xxxx" is what you are trying to match.

    0 讨论(0)
  • 2020-12-11 05:48

    grep -v -B1 doesnt work because it will skip those lines but will include them later on (due to the -B1. To check this out, try the command on:

    **document 1**                         -> 1
    **page 1 of 2**                        -> 2
    
    **document 1**
    **page 2 of 2**
    **page 3 of 2**
    

    You will notice that the page 2 line will be skipped because that line won't be matched and the next like wont be matched.

    There's a simple awk solution:

    awk '!/page.*of.*/ { if (m) print buf; buf=$0; m=1} /page.*of.*/ {m=0}' 1.txt
    

    The awk command says the following:

    If the current line has that "page ... of ", then it will signal that you haven't found a valid line. If you do not find that string, then you print the previous line (stored in buf) and reset the buffer to the current line (hence forcing it to lag by 1)

    0 讨论(0)
提交回复
热议问题