1

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.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Ishank Jain
  • 309
  • 5
  • 8
  • Please read [how-do-i-find-the-text-that-matches-a-pattern](https://stackoverflow.com/questions/65621325/how-do-i-find-the-text-that-matches-a-pattern) then [edit] your question to replace `pattern` with whatever you mean. Your example looks like you should be matching a string but your code is trying to match a regexp. – Ed Morton Dec 08 '22 at 14:19
  • You description does not accurately match your example--please clarify. – Andrew Dec 08 '22 at 14:37

5 Answers5

1

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
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
0

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.

Jeff Schaller
  • 2,352
  • 5
  • 23
  • 38
0

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$
Andrew
  • 1
  • 4
  • 19
0

This might work for you (GNU sed):

sed -E '/^#/{:a;N;/^property[^2]/Mb;/^property2/M!ba
             :b;/^#|^property2/!P;s/[^\n]*\n//;tb;d}' file

If a line is not a comment, let it be.

Otherwise, accumulate the lines in the pattern space.

If a subsequent line begins with a property that is not 2, print the accumulate lines and repeat.

If a subsequent line does not begin with property2, continue accumulating lines.

Otherwise, remove comments and print any lines other than the last which is deleted.

potong
  • 55,640
  • 6
  • 51
  • 83
0

Using gnu-sed with the -z commandline option to use NUL delimited records reading the whole input, and replace the match with an empty string:

sed -zE 's/(^|\n)#[^\n]*(\n#[^\n]*)*\nproperty2//g' test.txt

The pattern matches:

  • (^|\n)# Either match a newline or assert the start of the string
  • [^\n]* Match optional characters other than a newline
  • (\n#[^\n]*)* Optionally repeat matching a newline # and optional chars other than a newline
  • \nproperty2 Match a newline and property2

Output

# Comment
# Comment
# Comment
property1
The fourth bird
  • 154,723
  • 16
  • 55
  • 70