1
votes

I am trying to use awk to extract lines between two patterns, but as the second pattern involves multiple $$$$ sign I do not manage to protect properly the $

input is:

Name1
iii
iii
$$$$

Name2
ii
ooo
ppp
$$$$

Name3
pp
oo
ii
uu
$$$$

desired output

Name2
ii
ooo
ppp
$$$$

I tried something like this:

awk 'BEGIN {RS="\\$\\$\\$\\$\n"; FS="\n"} $1==Name2 {print $0; print "$$$$"}' inputfile

I also tried something like

awk '/^Name2/,/\\$\\$\\$\\$\\/' input

I tried many different protection of $ but i do it wrong, either nothing is printed or it prints the entire file

Many thanks for suggestions

3
I put a return after each $$$$ and tried something like awk 'BEGIN {RS="\\$\\$\\$\\$\n"; FS="\n"} $1==Name2 {print $0; print "$$$$"}' - BBVV94
can you add your code to the question? - TinyTheBrontosaurus
what is the actual output of that code? - TinyTheBrontosaurus
With GNU grep: grep -Poz '^Name2(\n.*?)*\$\$\$\$' file - Cyrus

3 Answers

2
votes

you don't have to use patterns if you're looking for a literal match

awk '$0=="Name2",$0=="$$$$"' file

will extract the lines between the two literals. Or a combination if the first match is a pattern

awk '/Name2/,$0=="$$$$"' file
1
votes

Awk solution:

awk '/^Name2/{ f=1 }f; $1=="$$$$"{ f=0 }' file
  • f variable is a marker indicating the possibility for the current line to be printed

The output:

Name2
ii
ooo
ppp
$$$$
1
votes

Instead of using $$$$ as the record separator, you may use the double empty lines, meaning splitting into paragraphs:

awk 'BEGIN{RS=""}/Name2/' file

RS="" is a special value. From the awk man page:

If RS is set to the null string, then records are separated by blank lines. When RS is set to the null string, the newline character always acts as a field separator, in addition to whatever value FS may have.


While the above code is fine for your example, you get into troubles when there are keys like Name20. Meaning a regex match might not be the right approach. An string comparison would probably be a better suite:

awk 'BEGIN{RS="";FS="\n"} $1 == "Name2"' file

I'm explicitly setting FS="\n" to avoid splitting within single lines.