如何在文本文件中进行多行模式匹配

时间:2021-02-05 04:21:39

标签: regex awk vim

我从测试结果中得到以下文件,该文件包含 100000 个或更多的测试用例条目。

文件内容:

Iteration is 1
Testcase is passed
Iteration is 2
Testcase is passed
Iteration is 3
Testcase is passed
Iteration is 4
Testcase is failed
Iteration is 5
Testcase is failed
Iteration is 6
Iteration is 7
Testcase is failed
Iteration is 8
Iteration is 9
Iteration is 10
Testcase is failed
Iteration is 11
Testcase is passed

对于某些测试用例迭代,如 689 判断缺失。这些迭代没有通过或失败。

我只想找到缺少哪个迭代测试用例的判断。

我在 gvim 中打开文件并尝试查找和删除像 Iteration is .*\n.*passedIteration is .*\n.*failed 这样的模式,但是没有用。

谁能建议如何找到没有类似结论的迭代

Iteration is 6
Iteration is 8
Iteration is 9

3 个答案:

答案 0 :(得分:2)

您可以使用以下正则表达式在任何合适的编辑器中进行“查找”:

Iteration is \d+\nTestcase is \w+\n

并用空字符串替换匹配项。

例如在vim中,假设光标在文件开头

:1,$s/Iteration is \d\+\nTestcase is \w\+\n//

成功了。

完成后,文件将包含没有计数失败/通过结果的行。

您也可以使用相同的策略来编写 perl 脚本 - 我把它留给您。

答案 1 :(得分:2)

这是一个简单的 Vim 解决方案:

:g/passed\|failed/norm k2dd

说明:

  • :g/<pattern>/<command> 在匹配 <command> 的每一行上执行 <pattern>

  • passed\|failed 是我们的模式。它匹配带有 passed 的行和带有 failed 的行。将 \| 视为“或”:“与 passedfailed 匹配”。

  • norm k2dd 是我们的命令。 :help :norm 用于在正常模式之外执行正常模式命令。我们在这里……

    • 使用k将光标移动到匹配行上方的行,
    • 使用 2dd 删除两行,有效地从文件中删除所有带有通过或失败测试用例的迭代。

我们在缓冲区中留下以下几行:

Iteration is 6
Iteration is 8
Iteration is 9

我们可以在获得所需信息后使用 u 还原该更改。

答案 2 :(得分:1)

请您尝试以下操作:

awk '
    /^Iteration/ {
        if (prev) print prev
        prev = $0
    }
    /^Testcase/ {
        prev = ""
    }
    END {
        if (prev) print prev
    }
' file.txt

结果:

Iteration is 6
Iteration is 8
Iteration is 9
  • 变量 prev 保存前一个 Iteration 记录。
  • 当记录以Iteration开头并且设置了变量prev时, 这意味着最后一个 Iteration 记录没有相应的通过/失败 记录。
  • 当记录以 Testcase 开头时,变量 prev 被清除。
  • END {} 块处理最后一次迭代。
相关问题