简体   繁体   中英

Unix Bash shell command to grep some text if another grep matches

I have an XML file in unix directory. I would like to search for some character if that is present, then grep the text located 3 lines before this matched line,.

Here is My File: (abc.xml)

<task Col="5" Object="BCD">
<checkpoint TcpOn="0"/>
<after ActFlg="0"/>
</task>
<task Col="6" Object="ABCD">
<checkpoint TcpOn="0"/>
<after ActFlg="1"/>
</task>
<task Col="7" Object="ABCDE">
<checkpoint TcpOn="0"/>
<after ActFlg="1"/>
</task>

Unix Code:

grep -i 'actflg="1"' abc.xml

Current Answer: This is returning the line where it is located.

<after ActFlg="1"/>
<after ActFlg="1"/>

What i Want is : (i want to do a further grep to display output as follows if actflg="1" is found...)

<task Col="6" Object="ABCD">
<task Col="7" Object="ABCDE">

You can use grep -B XX , which print XX lines before matching lines. Then you use head -1 to just print the first one:

$ grep -B2 -i 'actflg="1"' file
<task Col="6" Object="ABCD">
<checkpoint TcpOn="0"/>
<after ActFlg="1"/>

$ grep -B2 -i 'actflg="1"' file | head -1
<task Col="6" Object="ABCD">

In case there are multiple matches, you can do:

$ awk '/ActFlg="1"/ {print preprev} {preprev=prev; prev=$0}' file
<task Col="6" Object="ABCD">
<task Col="7" Object="ABCDE">

Explanation

  • '/ActFlg="1"/ {print preprev} matches lines containing ActFlg="1" and does print preprev , a stored line.
  • {preprev=prev; prev=$0} {preprev=prev; prev=$0} this keeps storing the two previous lines. The 2 before is stored in preprev and the previous in prev . So whenever we are in a new line, this gets updated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM