4

I have to search for a specific string in the reverse order and print it.

In the below example I want to search from the pattern not in order until the pattern number of.

Example: input file contains:

number of characters a[1] 
reg1 
reg2 
reg3 
info a[1] is not in order

number of characters a[3] 
reg1 
reg2 
reg3 
info a[3] is in order


number of characters a[2] 
reg1 
reg2 
reg3 
info a[2] is not in order

output should be:

number of characters a[1]
reg1 
reg2 
reg3 
info a[1] is not in order

number of characters a[2] 
reg1 
reg2 
reg3 
info a[2] is not in order
5
  • 1
    I don't understand why the second paragraph about a[3] is missing in the output. Can you elaborate?
    – Byte Commander
    Commented Aug 23, 2017 at 8:32
  • I don't want the second paragraph... I have to print only paragraph contains "not in order" Commented Aug 23, 2017 at 8:34
  • is it always 4 lines above "not in order" ?
    – pLumo
    Commented Aug 23, 2017 at 8:36
  • no , some paragraph having 5, 23, 100, 200 lines Commented Aug 23, 2017 at 8:38
  • Ah, now I see. Sorry, I didn't realize it says "is in order" there.
    – Byte Commander
    Commented Aug 23, 2017 at 8:46

4 Answers 4

4

Using in order with a newline as the paragraph delimiter, we can do:

awk -v RS='in order\n' '/not/{print $0 "in order"}'

awk treats text separated by the pattern in RS (record separator) as records, and each operation is done on a record. So /not/ tests if the record matches not, and then we print the record ($0) along with the separator text, which was removed by awk.

So:

$ mawk -v RS='in order\n' '/not/{print $0 "in order"}' foo
number of characters a[1]
reg1
reg2
reg3
info a[1] is not in order


number of characters a[2]
reg1
reg2
reg3
info a[2] is not in order
6
  • cant we grep only the pattern "not in order" until the pattern "number of" because I can see some of the paragraph are coming in between Commented Aug 23, 2017 at 8:53
  • Show us the sample text for which that happens.
    – muru
    Commented Aug 23, 2017 at 8:56
  • Warning info number of characters a[1] reg1 reg2 reg3 info a[1] is not in order number of characters a[3] reg1 reg2 reg3 info a[3] is in order helperflop number of characters a[2] reg1 reg2 reg3 info a[2] is not in order number of characters a[4] reg1 reg2 reg3 info a[4] is in order helperflop Commented Aug 23, 2017 at 9:10
  • 1
    you should check for / is not$/ (ie "is not" as end of line), to be safer on the boundary matching Commented Aug 23, 2017 at 9:30
  • 1
    @OlivierDulac good idea, but in this case I think the problem is more in extra text in the lines (I see helperflop in the comments above, but without formatting, I cannot really make out where it belongs)
    – muru
    Commented Aug 23, 2017 at 9:32
3

If the blocks have to end with a line that contains is in order or is not in order, we can delete things between them...

$ sed '/is not in order/,/is in order/ {/is not in order/n;d}' file
number of characters a[1] 
reg1 
reg2 
reg3 
info a[1] is not in order


number of characters a[2] 
reg1 
reg2 
reg3 
info a[2] is not in order

Notes:

  • /is not in order/,/is in order/ find the lines between is not in order and is in order, inclusive
  • {some commands} group these commands
  • /is not in order/n skip the line with this pattern from the next command
  • d delete the specified lines

It might seem convoluted to find the line and then find it again to skip it, but we can't use an empty line instead, or sed will turn on its operate here flag at the next empty line and keep going until the next is in order, which will delete too much.

3

another approach:

tac file | awk ' BEGIN {weprint=0 ; rem="not necessary, but for clarity"}
  /is not in order$/ { weprint=1 ;}
  ( weprint == 1)    { print $0  ;   rem="same remark here..."; }
  /^number of/       { weprint=0 ;}
' | tac

which could be shortened if needed...

If you want the separator line: change the last line as

"/^number of/" { print ; weprint=0;}
2
perl -00 -ne 'print if /not in order/' file

The -00 option reads the file by paragraphs.
The -n adds an implicit loop over all the paragraphs in the file.
Then, print the paragraph if it contains the desired text "not in order".

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .