简体   繁体   English

使用sed删除所有不匹配模式的行

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

Very new (meaning a day) to sed. 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. 我试图拥有它,所以当一切都说完之后,我试图保留三行(item4&item5)并删除所有其他行。 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... 编辑 :此答案是在需要保留item4item5之后item4 next行的编辑之前2小时给出的...

This might work for you (GNU sed): 这可能对您有用(GNU sed):

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

Delete all lines not between config and end . 删除不在configend之间的所有行。 Print lines that begin config or end and lines that start with item4 or item5 and the following two lines. 打印以configend开头的行以及以item4item5以及以下两行。

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): 我将其范围缩小为四个命令,您可以将其放入bash脚本中(用您自己的源文件替换file.txt ,用所需的任何目标替换/tmp/finalFile ):

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 : 当我运行以上命令时,这是/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 第一行只是head finalFile的第一行,附加到finalFile
  • The second step is basically look for every line up to item5 , and save that in a temp file. 第二步基本上是查找直到item5每一行,并将其保存在临时文件中。
  • 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 . 第三步获取该临时文件,并计算需要tail多少行,以使所有行达到item6 (不包括它),然后获取这些行,并将输出追加到finalFile
  • Finally, the last line grabs the last line from the original file with tail , and appends that to finalFile 最后,最后一行使用tail finalFile原始文件的最后一行,并将其追加到finalFile

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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