0

There is file with lines, say

Sec #1 SectionA
      ..................
      ..................
      ..mypattern.......
      ..................

Sec #2 SectionB
      ..................
      .......mypattern..
      ..................
    .
    .
    .
Sec #n SectionN

This pattern will only be present in some sections and I would like to search on mypattern and get the section names (SectionA, SectionB etc..) containing the mypattern.

How to get it? I have tried with grep, sed, pcre2grep but wasn't able to get names.

awk '/Sec/,/mypattern
grep -oz 'Sec.*mypattern'
pcre2grep -M 'Sec.*(\n|.)*?mypattern'

Clarifications:

  • mypattern is just a string, no regex
Sriteja Sugoor
  • 574
  • 3
  • 13
  • 1
    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) to understand why this matters and then replace the word "pattern" with string-or-regexp and full-or-partial word-or-line everywhere it appears in your question so we can help you. – Ed Morton Jul 20 '21 at 19:19

3 Answers3

2

You may use an empty RS to break down input on an empty line:

awk -v RS= '/mypattern/ {print $3}' file

SectionA
SectionB
anubhava
  • 761,203
  • 64
  • 569
  • 643
0

Awk will loop over all lines in input_file and for each line

  • If the line starts with "Sec", set section to the third column of the line and set printed to 0
  • If the line doesn't start with "Sec", and printed is 0, and the line matches "mypattern", then print the value of the section and set printed to 1
awk '{
if ($1 ~ "^Sec") {
  section = $3
  printed = 0
}
else if (!printed && $0 ~ "mypattern") {
  print section
  printed++
}
}' input_file

If you prefer to be more concise, you could do the same thing with

awk '/^Sec/{sec = $3; next} /mypattern/{print sec}' input_file | uniq

With input file as

Sec #1 SectionA
      ..................
      ..................
      ..mypattern.......
      ..................

Sec #2 SectionB
      ..................
      .......mypattern..
      ..................
    .
    .
    .
Sec #2 SectionC
    ... nonmatching stuff ...
Sec #n SectionN

You get this output:

SectionA
SectionB
IceCreamToucan
  • 28,083
  • 2
  • 22
  • 38
0

This might work for you (GNU sed):

sed -n '/^Sec /h;G;/mypattern/s/.* //p' file

Make a copy of the section name line.

Append the copy to each line and match on mypattern.

If the match is successful, remove all but the section name and print the result.

potong
  • 55,640
  • 6
  • 51
  • 83