Get lines between pattern1 and pattern2 into a sep

2019-09-06 11:02发布

I have a text file with thousands of lines as below

`DEFINE OBJECT('OBJECT.TOPIC') +
*  ALTDATE(2015-09-22) +
*  ALTTIME(00.56.38) +
   DESCR('topic object') +
   GET(ENABLED) +
   PUT(ENABLED) +
   PROPCTL(COMPAT) +
   TARGTYPE(TOPIC) +
   REPLACE
DEFINE OBJECT('OBJECT1') +
*  CRDATE(2015-09-22) +
*  CRTIME(00.56.38) +
*  CURDEPTH(0) +
   CUSTOM(' ') +
   DESCR('TEST') +
   DISTL(NO) +
   PROCESS(' ') +
   SHARE +
   USAGE(NORMAL) +
   REPLACE
DEFINE OBJECT('OBJECT2') +
*  ALTDATE(2015-09-22) +
*  ALTTIME(00.56.38) +
*  CURDEPTH(0) +
   CUSTOM(' ') +
   DESCR('TEST') +
   DISTL(NO) +
   PROCESS(' ') +
   SHARE +
   USAGE(NORMAL) +
   REPLACE
DEFINE OBJECT('TCOBJECT1') +
*  CRDATE(2015-09-22) +
*  CRTIME(00.56.38) +
*  CURDEPTH(0) +
   CUSTOM(' ') +
   DESCR('TEST') +
   DISTL(NO) +
   PROCESS(' ') +
   SHARE +
   USAGE(NORMAL) +
   REPLACE
SET RECORD +
   PROFILE('OBJECT2') +
   GROUP('user1') +
   AUTHADD(change,delete,display,alter)
SET RECORD +
   PROFILE('TCOBJECT1') +
   GROUP('user3') +
   AUTHADD(change,delete,display,alter)
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user1') +
   AUTHADD(change,delete,display,alter)
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user2') +
   AUTHADD(change,delete,display,alter)
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user3') +
   AUTHADD(change,delete,display,alter)`

Now, i want to get the blocks containing matching the pattern OBJECT1.

`DEFINE OBJECT('OBJECT1') +
*  CRDATE(2015-09-22) +
*  CRTIME(00.56.38) +
*  CURDEPTH(0) +
   CUSTOM(' ') +
   DESCR('TEST') +
   DISTL(NO) +
   PROCESS(' ') +
   SHARE +
   USAGE(NORMAL) +
   REPLACE
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user1') +
   AUTHADD(change,delete,display,alter)
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user2') +
   AUTHADD(change,delete,display,alter)
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user3') +
   AUTHADD(change,delete,display,alter)`

I have tried with awk and sed to get atleast the first part. but it's not stopping after the first match of pattern2. I am running these commands just to get the first block atleast..

awk '/OBJECT1/ {p=1}; p; $0=="REPLACE" {p=0}' objlist.txt > obj1list.txt 

awk '$0=="OBJECT1" {p=1}; p; $0=="REPLACE" {p=0}' objlist.txt > obj1list.txt

cat objlist.txt | sed  -n '/OBJECT1/p;/REPLACE/q' > obj1list.txt 

But these dont work.Please help

As per the suggested answer, i am using awk -vRS="[^+]\n" 'BEGIN{printf "`"}/\/{printf $0 RT}' and getting the required output. However now i want to remove the block containing user2 and user3 from the output obtained by using the above command.

4条回答
三岁会撩人
2楼-- · 2019-09-06 11:07

awk to the rescue! (with little help from sed)

$ sed -r 's/^([^* ])/\n\1/' file | awk -v RS= '/OBJECT1/'

will print

DEFINE OBJECT('OBJECT1') +
*  CRDATE(2015-09-22) +
*  CRTIME(00.56.38) +
*  CURDEPTH(0) +
   CUSTOM(' ') +
   DESCR('TEST') +
   DISTL(NO) +
   PROCESS(' ') +
   SHARE +
   USAGE(NORMAL) +
   REPLACE
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user1') +
   AUTHADD(change,delete,display,alter)
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user2') +
   AUTHADD(change,delete,display,alter)
SET RECORD +
   PROFILE('OBJECT1') +
   GROUP('user3') +
   AUTHADD(change,delete,display,alter)`

ps. Note that the start quote is not printed since it's not on the extracted line.

For more targeted matches you can combine the quote as part of the pattern. However, in awk it has special meaning and should be treated. I use the following approach.

$ ... | awk -v RS= -vq="'" '$0 ~ q"OBJECT1"q'
查看更多
爷的心禁止访问
3楼-- · 2019-09-06 11:11
awk -vRS="[^+]\n" 'BEGIN{printf "`"}/\<OBJECT1\>/{printf $0 RT}' a
查看更多
虎瘦雄心在
4楼-- · 2019-09-06 11:13

This might work for you (GNU sed):

sed '/^\w/!{H;$!d};x;/\bOBJECT1\b/p;x;h;d' file

If it is not the start of a record append it to the hold space (HS) and if it is not the last line delete it. Otherwise it is either the start of a record or the last line in which case: check the HS for the required string and print if found and then replace the HS with the start of the record.

查看更多
Summer. ? 凉城
5楼-- · 2019-09-06 11:17
awk 'BEGIN{RS="DEFINE OBJECT"}{if($1~/\('\''OBJECT1'\''\)/){print$0}}' my_file
查看更多
登录 后发表回答