打印范围从某个模式的最后一次出现到另一个模式的第一次出现

Hen*_*nry 5 sed awk text-processing

早上好,这与问题Grep From the Last Occurrence of a Pattern to Another Pattern(几个月前)非常相似,同时添加了更多细节。

我正在尝试为具有多个重复模式的文件编写 UNIX 脚本,然后是我正在寻找的模式。但是我没有 'tac' 或 'tail -r'(使用 UNIX 模拟器,MKS Toolkit),我希望返回 Pattern2 之前最后一次出现的 Pattern1,然后是 Pattern1 和 Pattern2 之间的数据,然后是 Pattern2还。在这种情况下,模式将是“条件 1”和“条件 2”:

输出:

...
Condition 1: A
data1
Condition 1: B
data2
Condition 2: C
data3
Condition 1: D
data4
Condition 1: E
data5
Condition 2: F
...
Run Code Online (Sandbox Code Playgroud)

我想编写一个 awk(或 sed,但认为 awk 是正确的工具)脚本来返回:

Condition 1: B
data2
Condition 2: C
Condition 1: E
data5
Condition 2: F
Run Code Online (Sandbox Code Playgroud)

我认为这是下面一行的某种形式,但我无法正确使用语法:

awk '/Condition 1/ {acc = $0;} /,/Condition 2/ {print ?}' output.out
Run Code Online (Sandbox Code Playgroud)

使用 '/,/' 似乎是我遇到问题的地方。想知道是否有人有任何建议,将不胜感激。非常感谢与此问题相关的任何帮助和时间。

Joh*_*024 5

尝试:

$ awk 'f{a=a"\n"$0} /Condition 1/{a=$0; f=1} f && /Condition 2/{print a; f=0}' output.out 
Condition 1: B
data2
Condition 2: C
Condition 1: E
data5
Condition 2: F
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

  • f{a=a"\n"$0}

    如果变量f为真(非零),则将当前行追加到变量的末尾a

  • /Condition 1/{a=$0; f=1}

    如果当前行包含Condition 1,则设置s为当前行并将变量设置f为 1。

  • f && /Condition 2/{print a; f=0}

    如果f为真且当前行包含Condition 2,则打印变量a并设置f回零。


Wil*_*ard 5

当您想在文本处理中进行反向寻址时,请使用 ex

它是POSIX 指定的,它是vi(以及它的vi直接前身)的可编写脚本的形式——非常灵活。

printf '%s\n' 'g/Condition 2/?Condition 1?,.p' | ex output.out
Run Code Online (Sandbox Code Playgroud)

这意味着:

对于g匹配模式“条件 2”的每一行(局部),向后搜索“条件 1”的前一个实例,并将p所有行从该行到当前行 ( .)(即带有“条件 2”的行)它)。

提供的输入上的输出与您描述的完全相同。