CzarMatt
CzarMatt

Reputation: 1833

How to match nested text prefixed with spaces in sed or grep

I am trying to match nested text, including the line immediately prior to the nested text with sed or grep.

An example of what I'm working with:

pattern3
    abcde
    fghij
pattern3
pattern1
    abcde
    fghij
pattern1
pattern1
    klmno
pattern1
pattern3
    abcde
pattern1
    pqrst
patterh3
    fghij

Note that there are always four (4) spaces prefixing the nested text. Also, there may or may not be nested text after a matching pattern.

I'm interested in all pattern1 lines, plus the lines following pattern1 that are proceeded by spaces.

The output I'm looking for is:

pattern1
    abcde
    fghij
pattern1
pattern1
    klmno
pattern1
pattern1
    pqrst

I got close with:

sed -n '/^pattern1/,/^pattern1/p' data.txt

But it seems to skip nested text after the right hand side pattern1 match, and move onto the next iteration.

I also tried sed -n '/^\"pattern1\"$/,/^\"pattern1\"$/p' data.txt | sed '1d;$d' with no luck either.

Upvotes: 2

Views: 491

Answers (4)

potong
potong

Reputation: 58558

This might work for you (GNU sed):

sed '/^\S/h;G;/pattern1/P;d' file

Store the current pattern in the hold space and append it to each line. If the current pattern is pattern1, print the current line and/or delete the current line.

Upvotes: 1

Ed Morton
Ed Morton

Reputation: 204548

$ awk '/^[^ ]/{f=/^pattern1$/} f' file
pattern1
    abcde
    fghij
pattern1
pattern1
    klmno
pattern1
pattern1
    pqrst

Upvotes: 1

Cyrus
Cyrus

Reputation: 88939

With GNU sed:

sed -n '/pattern1/{p;:x;n;s/^    .*/&/;p;tx}' file

or simplified:

sed -n '/pattern1/{p;:x;n;p;/^    /bx}' file

Output:

pattern1
    abcde
    fghij
pattern1
pattern1
    klmno
pattern1
pattern1
    pqrst

Upvotes: 2

RavinderSingh13
RavinderSingh13

Reputation: 133760

Could you please try following.

awk '/pattern[23]/{flag=""} /pattern1/{flag=1} flag'  Input_file

OR

awk '/pattern[^1]/{flag=""} /pattern1/{flag=1} flag'  Input_file

Explanation: Adding explanation too here.

awk '
/pattern[^1]/{        ##Checking condition if a line is having string pattern with apart from digit 1 in it then do following.
  flag=""             ##Nullifying variable flag value here.
}
/pattern1/{           ##Checking condition here if a line is having string pattern1 then do following.
  flag=1              ##Setting value of variable flag as 1 here.
}
flag                  ##Checking condition if value of flag is NOT NULL then print the line value.
' Input_file          ##Mentioning Input_file name here.

Upvotes: 1

Related Questions