如果内部包含一些文本,请删除html标记

时间:2011-04-22 16:54:42

标签: linux bash sed

如果div的子节点与某些字符串匹配,我想删除整个div。例如:

<div>
some text here
if this text is matched, remove whole div
some other text
</div>

我必须在许多文件上执行此操作,因此我正在寻找一些Linux命令,如sed。

感谢您对此进行调查。

3 个答案:

答案 0 :(得分:1)

如果我理解你的问题,那么可以用一个单独的sed命令来实现:

sed '/<div>/I{:A;N;h;/<\/div>/I!{H;bA};/<\/div>/I{g;/\bsome text here\b/Id}}' file.txt

测试

假设这是你的file.txt:

a. no-div text

<DIV>

some text here
1. if this text is matched, remove whole DIV
some other text -- WILL MATCH
</div>

<div>
awesome text here
2. if this text is matched, remove whole DIV
this will NOT be matched
</div>

b. no-div text

<Div>
another text here
3. if this text is matched, remove whole DIV
and this too will NOT be matched
</Div>

<div>
Some TEXT Here
4. if this text is matched, remove whole DIV
foo bar foo bar - WILL MATCH
</DIV>

c. no-div text

现在,当我运行sed命令时,它会输出:

a. no-div text


<div>
awesome text here
2. if this text is matched, remove whole DIV
this will NOT be matched
</div>

b. no-div text

<Div>
another text here
3. if this text is matched, remove whole DIV
and this too will NOT be matched
</Div>


c. no-div text

正如您可以从上面的输出验证,some text here标记之间的模式div匹配的地方已经完全删除了这些div块。

PS:我在这里进行不区分大小写的搜索,如果您不需要这种行为,请告诉我。我只需要从上面的sed命令中删除I切换。

答案 1 :(得分:0)

这可能是一种更好的方法,但我过去所做的是:

1)删除换行符(因为跨行匹配很困难,后退甚至更糟)

2)解析

3)将换行符放回

cat /tmp/data | tr "\n" "@" | sed -e 's/<div>[^<]*some text here[^<]*<\/div>//g' | tr "@" "\n"

这假设“@”不能出现在文件中。

答案 2 :(得分:0)

您可以使用ed而不是sed。 ed命令将整个文件读入内存并执行就地文件编辑(即没有安全备份)。

htmlstr='
<see file.txt in answer by anubhava>
'
matchstr='[sS][oO][mM][eE]\ [tT][eE][xX][tT]\ [hH][eE][rR][eE]'
divstr='[dD][iI][vV]'
# for in-place file editing use "ed -s file" and replace ",p" with "w"
# cf. http://wiki.bash-hackers.org/howto/edit-ed
cat <<-EOF | sed -e 's/^ *//' -e 's/ *$//' -e '/^ *#/d' | ed -s <(echo "$htmlstr")
  H
  # ?re?   The previous line containing the regular expression re.  (see man ed)
  # '[[:<:]]' and '[[:>:]]' match the null string at the beginning and end of a word respectively. (see man re_format)
  #,g/[[:<:]]${matchstr}[[:>:]]/?<${divstr}>?,/<\/${divstr}>/d
  ,g/[[:<:]]${matchstr}[[:>:]]/?<${divstr}>?+0,/<\/${divstr}>/+0d
  ,p
  q
EOF