Home > OS >  Delete a pattern in a file and lines before it using some other pattern
Delete a pattern in a file and lines before it using some other pattern

Time:12-09

I have a text file containing this :-

# Comment
# Comment
# Comment
property1

# Comment
# Comment
property2

I wanted to use unix command (awk/sed etc.) to search for a pattern with property2 and then delete all the comments before it. Hence, after operation output should be :-

# Comment
# Comment
# Comment
property1

This is what I tried (using awk command) :-

awk -v pat='^property2' -v comment='^#' '$1~pat{p=NR} p && NR>=p-3{del=($1~comment)} del{next} 1' test.txt

Basically, the logic I tried to use was :-

  1. Search for property2
  2. and then loop over previous 3 lines
  3. Search if it is a comment (starts with #)
  4. Delete those lines (including the searched pattern and the comments above).

Can someone help me achieve this? Thanks.

CodePudding user response:

This, using any awk, might be what you're trying to do but it's not clear from your question:

$ awk -v RS= -v ORS='\n\n' -F'\n' '$NF != "property2"' file
# Comment
# Comment
# Comment
property1

CodePudding user response:

You could use a scriptable editor such as ed to:

  1. Search for the first match of property2 (anchored to the beginning of the line)
  2. Search backwards from there for a line that does not start with #
  3. From the line after this one until one that starts with property2, delete those lines
  4. write the file out to disk
  5. quit the editor

One way to write that would be:

#!/bin/sh

printf '%s\n'             \
        '/^property2'     \
        '?^[^#]'          \
        ' 1,/^property2/d' \
        'w'               \
        'q'               \
  | ed input > /dev/null

I've dropped the stdout of ed to /dev/null because it will report the lines that it matches along the way, which we're not interested in. ed will make the changes to the file "in-place". This ed-script will fail if there is not a non-empty, non-commented line before property2 (the backwards search will fail).

In your sample input, this will delete the blank line between the stanzas as well, which seems to match your desired output.

CodePudding user response:

It is not clear what you are trying to do; maybe this is it:

Mac_3.2.57$cat test.txt
# Comment1
# Comment2
# Comment3
property1

# Comment4
# Comment5
property2
Mac_3.2.57$awk '{if(NR==FNR){{if($0!~/^#/&&startFound==1){startFound=0;end=NR};if($0~/^#/&&startFound==0){startFound=1;start=NR}}}else {if(FNR<start||FNR>=end){print}}}' test.txt test.txt
# Comment1
# Comment2
# Comment3
property1

property2
Mac_3.2.57$
  • Related