首页 > 解决方案 > grep 一个词,需要为该特定标签替换上述行

问题描述

我有如下所示的 HTML 代码:

<html>
<head>
<style>
table, th, td {
border:1px solid black;border-collapse:collapse
}
</style>
</head>
<body>
<table style=width:30%>
<tr>
<td>version2</td>
<td>FAIL</td>
</tr>
<tr>
<td>version1</td>
<td>FAIL</td>
</tr>
<tr>
<td>version6</td>
<td>PASS</td>
</tr>

每当我在标签中看到关键字 FAIL 时,我需要替换上面的代码,如下所示。对于 PASS 不需要做任何事情。

<html>
<head>
<style>
table, th, td {
border:1px solid black;border-collapse:collapse
}
</style>
</head>
<body>
<table style=width:30%>
<tr bgcolor="red">
<td>version2</td>
<td>FAIL</td>
</tr>
<tr bgcolor="red">
<td>version1</td>
<td>FAIL</td>
</tr>
<tr>
<td>version6</td>
<td>PASS</td>
</tr>

使用 sed 我可以搜索一个单词,我可以使用以下命令替换它:

sed -i 's/<tr>/<tr bgcolor="red">/g'

但就我而言,首先我需要搜索 FAIL 关键字,然后<tr>需要替换该特定标签。

标签: bashshellawksedgrep

解决方案


使用 GNU awk,定义多字符记录分隔符:

awk -v RS='<tr>' 'NR > 1 { rs = /FAIL/ ? "<tr bgcolor=\"red\">" : RS } { printf "%s%s", rs, $0 }' file

这使用开始标签作为记录分隔符,并在匹配记录的任何部分时<tr>替换它。/FAIL/

我们使用NR > 1这样它只在第一条记录之后开始发生,以避免<tr>在输出开始时获得额外的。对于第一条记录(直到<tr>输入中的第一条),rs未设置,因此在打印时将评估为空字符串。


推荐阅读