如何在模式重复时删除模式之间的线

时间:2015-08-05 16:40:26

标签: shell awk sed gawk

有一个大型HTML文档,其中BEGINEND的字词在整个文档中重复出现。 例如,BEGIN为<script>,END为</script>。 对于文档中模式的每个实例,模式之间存在可变数量的行(<script></script>之间)。

sed中尝试了以下内容:

sed '/\<script>/,/\<\/script>/d'

sed字符串会删除第一次出现<script>最后出现</script>之间的所有内容。

也尝试过:

awk '/\<script>/,/\<\/script>/d'

awk字符串删除模式之间的所有内容,但与sed字符串不同,它会保留模式的每次出现,如下所示:

<script>
</script>

总之,我可以得到我想要的变体(或其相反的变体)。

  • sed删除模式(一个实例)之间的文本
  • awk维护所有出现的模式,但删除模式之间的内容,以及模式之前和之后的内容。

我的问题:使用sed或awk(和/或任何其他GNU实用程序),如何在定义模式的术语(BEGIN术语和END term)在文档中多次出现?

5 个答案:

答案 0 :(得分:2)

$ cat file
a
<script>
b
</script>
c
<script>
d
</script>
e

$ awk '/<script>/{f=1} !f; /<\/script>/{f=0}' file
a
c
e

答案 1 :(得分:1)

另一个awk替代

awk '/\<script/{p=1};/\/script/{p=0;;next}; !p' file.html

答案 2 :(得分:0)

sed适合我。你确定它删除了第一次和最后一次之间的所有内容吗?

for i in {1..20} ; do
    echo $i
    (( 0 == i % 7 )) && echo '<script>'
    (( 0 == i % 8 )) && echo '</script>'
done | sed '\=<script>=,\=</script>=d'

输出:

1
2
3
4
5
6
7
9
10
11
12
13
14
17
18
19
20

要查看已删除的部分,请在!

之前添加d
... | sed '\=<script>=,\=</script>=!d'
<script>
8
</script>
<script>
15
16
</script>

答案 3 :(得分:0)

尝试:

awk '/<script>/,/<\/script>/{next}1' 

答案 4 :(得分:0)

据我了解您的问题,您希望删除(如您所述)BEGINEND之间的所有行,同时保留行BEGINEND。 如果是这样,这对您有用:

sed  '/\<script>/,/\<\/script>/ { /<script>/n; /\<\/script>/ !{ d; }; }' input_file

输入:

<html>
 <head>
 <title></title>
<body>
 <script>
SOME SCRIPT
</script>
 <script>
SOME OTHER SCRIPT
 </script>
</head>
</body>
</html>

输出:

<html>
 <head>
 <title></title>
<body>
 <script>
</script>
 <script>
 </script>
</head>
</body>
</html>