尝试使用 awk 在文件中查找两个字符串的匹配项
Trying to find a match of two strings in a file using awk
你好,我正在尝试使用 AWK 在一些 HTML 文件上找到模式匹配,但我似乎没有任何运气
所以要匹配我的模式,它应该具有以下内容
<tr>
<td>Failures</td>
<td>0</td>
</tr>
<tr>
<td>Warnings</td>
<td>4</td>
</tr>
<tr>
<td>Errors</td>
<td>0</td>
</tr>
<tr>
<td>Not Applicable</td>
<td>53</td>
</tr>
<tr>
<td>Manual Checks</td>
<td>9</td>
</tr>
故障和手动检查应为零。所以在上面的文件中失败是0,手动检查是9。所以我只需要在失败是0,手动检查是0时匹配。
所以我尝试了转义和不转义新行,但是 awk 没有返回任何结果。
find . -name "*.html" -exec awk '/td\>Failures\<\/td\>\n.*\<td\>0/ {print FILENAME}' '{}' \;
我也试过像下面这样的其他组合,但似乎无法弄清楚为什么 awk 不会转到下一行。
find . -name "*.html" -exec awk '/td\>Failures\<\/td\>\n\[\^\\<\]\+\<td\>0/ {print FILENAME}' '{}' \;
任何人都可以看看并告诉我我缺少什么吗?
更可靠的解决方案将基于旨在解析 html
的工具;话虽如此...
一个 awk
使用几个自定义正则表达式模式的想法:
$ cat regex.awk
BEGIN { RS="^$" # whole file treated as a single line of input
regex1="<td>Manual Checks</td>[[:space:]]+<td>0</td>"
regex2="<td>Failures</td>[[:space:]]+<td>0</td>"
}
[=10=] ~ regex1 && [=10=] ~ regex2 {print FILENAME}
注意: 将代码放在文件中 (regex.awk
) 将使 follow-on find/awk
更清晰一些
示例输入:
$ cat f1.html
... snip ...
<td>Failures</td>
<td>0</td> # match
... snip ...
<td>Manual Checks</td>
<td>9</td> # not a match
... snip ...
$ cat f2.html
... snip ...
<td>Failures</td>
<td>0</td> # match
... snip ...
<td>Manual Checks</td>
<td>0</td> # match
... snip ...
注意: 添加注释以进行说明;注释在实际文件中不存在
将此添加到 find
调用:
$ find . -name "f?.html" -exec awk -f regex.awk '{}' \;
./f2.html
如果您的 html 文件是 well-formed xml,那么 xmlstarlet 将起作用:
find . -name '*.html' \
-exec xmlstarlet sel -t \
--if '//tr[td[1] = "Failures" and td[2] = "0"]' \
--if '//tr[td[1] = "Manual Checks" and td[2] = "0"]' \
--inp-name --nl \
'{}' \;
- 如果有一行的第一个单元格是 Failures 而第二个单元格是 0,
- 如果有一行的第一个单元格是手动检查,第二个单元格是 0,
- 然后打印输入的文件名和换行符。
在每个 Unix 机器上的任何 shell 中使用任何 awk:
$ cat tst.awk
gsub("^[[:space:]]*<td>|</td>[[:space:]]*$","") {
if ( ++cnt % 2 ) {
tag = [=10=]
}
else {
f[tag] = [=10=]+0
}
}
END {
if ( (f["Failures"] == 0) && (f["Manual Checks"] == 0) ) {
print FILENAME
}
}
$ awk -f tst.awk file
上面创建了一个数组 f[]
,它将单元格的标签(名称)映射到它们的值,这样在 END 部分中,您可以对它们的任何组合进行任何测试。
你好,我正在尝试使用 AWK 在一些 HTML 文件上找到模式匹配,但我似乎没有任何运气
所以要匹配我的模式,它应该具有以下内容
<tr>
<td>Failures</td>
<td>0</td>
</tr>
<tr>
<td>Warnings</td>
<td>4</td>
</tr>
<tr>
<td>Errors</td>
<td>0</td>
</tr>
<tr>
<td>Not Applicable</td>
<td>53</td>
</tr>
<tr>
<td>Manual Checks</td>
<td>9</td>
</tr>
故障和手动检查应为零。所以在上面的文件中失败是0,手动检查是9。所以我只需要在失败是0,手动检查是0时匹配。
所以我尝试了转义和不转义新行,但是 awk 没有返回任何结果。
find . -name "*.html" -exec awk '/td\>Failures\<\/td\>\n.*\<td\>0/ {print FILENAME}' '{}' \;
我也试过像下面这样的其他组合,但似乎无法弄清楚为什么 awk 不会转到下一行。
find . -name "*.html" -exec awk '/td\>Failures\<\/td\>\n\[\^\\<\]\+\<td\>0/ {print FILENAME}' '{}' \;
任何人都可以看看并告诉我我缺少什么吗?
更可靠的解决方案将基于旨在解析 html
的工具;话虽如此...
一个 awk
使用几个自定义正则表达式模式的想法:
$ cat regex.awk
BEGIN { RS="^$" # whole file treated as a single line of input
regex1="<td>Manual Checks</td>[[:space:]]+<td>0</td>"
regex2="<td>Failures</td>[[:space:]]+<td>0</td>"
}
[=10=] ~ regex1 && [=10=] ~ regex2 {print FILENAME}
注意: 将代码放在文件中 (regex.awk
) 将使 follow-on find/awk
更清晰一些
示例输入:
$ cat f1.html
... snip ...
<td>Failures</td>
<td>0</td> # match
... snip ...
<td>Manual Checks</td>
<td>9</td> # not a match
... snip ...
$ cat f2.html
... snip ...
<td>Failures</td>
<td>0</td> # match
... snip ...
<td>Manual Checks</td>
<td>0</td> # match
... snip ...
注意: 添加注释以进行说明;注释在实际文件中不存在
将此添加到 find
调用:
$ find . -name "f?.html" -exec awk -f regex.awk '{}' \;
./f2.html
如果您的 html 文件是 well-formed xml,那么 xmlstarlet 将起作用:
find . -name '*.html' \
-exec xmlstarlet sel -t \
--if '//tr[td[1] = "Failures" and td[2] = "0"]' \
--if '//tr[td[1] = "Manual Checks" and td[2] = "0"]' \
--inp-name --nl \
'{}' \;
- 如果有一行的第一个单元格是 Failures 而第二个单元格是 0,
- 如果有一行的第一个单元格是手动检查,第二个单元格是 0,
- 然后打印输入的文件名和换行符。
在每个 Unix 机器上的任何 shell 中使用任何 awk:
$ cat tst.awk
gsub("^[[:space:]]*<td>|</td>[[:space:]]*$","") {
if ( ++cnt % 2 ) {
tag = [=10=]
}
else {
f[tag] = [=10=]+0
}
}
END {
if ( (f["Failures"] == 0) && (f["Manual Checks"] == 0) ) {
print FILENAME
}
}
$ awk -f tst.awk file
上面创建了一个数组 f[]
,它将单元格的标签(名称)映射到它们的值,这样在 END 部分中,您可以对它们的任何组合进行任何测试。