简体   繁体   中英

Using sed to remove all lines that don't match a pattern

Very new (meaning a day) to sed. I have worked a way to remove the lines that I do not need for an updated file with find/replace of a singular command

I have a list of objects as follows from a fortigate configuration:

config firewall address <--keep line
edit "item1"
next
edit "item2"
next
edit "item3"
next
edit "item4" <--keep line
unset associated-interface <--keep line and use as anchor for one line above and below
next <--keep line
edit "item5" <--keep line
unset associated-interface <--keep line and use as anchor for one line above and below
next <--keep line
edit "item6"
next
end <--keep line

I am trying to have it so when it is all said and done I am trying to keep the three lines (item4 & item5) and remove all of the other lines. Also, if possible keep the first and last line.

Your description lacks a great deal of precision, but here goes something :

sed -n -e '/^config/p;/item[45]/p;/^end/p' forti
config firewall address
edit "item4"
edit "item5"
end

Edit : this answer was given 2 hours before the edit that required the lines up to and following next after the item4 and item5 to be kept...

This might work for you (GNU sed):

sed '/config/,/end/!d;/config/b;/end/b;/item4/,+2b;/item5/,+2b;d' file

Delete all lines not between config and end . Print lines that begin config or end and lines that start with item4 or item5 and the following two lines.

This is probably not the best way to do it, but I couldn't find any other way around it.

I narrowed it down to four commands, which you can put in a bash script (replace file.txt with your own source file, and /tmp/finalFile with whatever destination you need):

head -n1 file.txt >> /tmp/finalFile
head -n $(echo $(grep -ni item6 file.txt | cut -d: -f1) - 1 | bc) file.txt > /tmp/tmpfile
tail -n $(echo $(wc -l /tmp/tmpfile | awk '{print $1}') - $(grep -n item4 /tmp/tmpfile | cut -d: -f1) + 1 | bc) /tmp/tmpfile >> /tmp/finalFile
tail -n1 file.txt >> /tmp/finalFile

When I ran the above commands, this is the final file in /tmp/finalFile :

config firewall address 
edit "item4" 
unset associated-interface  
next 
edit "item5" 
unset associated-interface 
next 
end 

Some explanation:

  • The first line is simply the top line grabbed by head , appended to finalFile
  • The second step is basically look for every line up to item5 , and save that in a temp file.
  • The third step grabs that temp file, and calculates how many lines it needs to tail , to get all the lines up to item6 , not including it, and grabs those lines, appending the output to finalFile .
  • Finally, the last line grabs the last line from the original file with tail , and appends that to finalFile

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