2

假设我有文件:

1Alorem
2ipsuml
3oremip
4sumZAl
5oremip
6sumlor
7emZips

我想将文本从包含 A 的行拆分为包含 Z 与范围匹配的行:

/A/,/Z/ {
print > "rangeX.txt"
}

我希望这个特定的输入给我 2 个文件:

1Alorem
2ipsuml
3oremip
4sumZAl

4sumZAl
5oremip
6sumlor
7emZips

问题是第 4 行仅在 ad 匹配为范围结束时才被采用,但第 2 范围永远不会开始,因为其他行中没有 A。

有没有办法尝试再次将第 4 行与所有模式匹配或告诉 awk 它必须开始新的范围?

谢谢

4

3 回答 3

2

正如 Arne 指出的,第二部分不会被捕捉到,而是当前的模式。这是没有范围的替代方案。

awk 'p==0 {p= (~/A/)>0;filenr++} p==1 {print > "range"filenr".txt"; p= (~/Z/)==0; if(!p && ~/A/){filenr++;;p=1; print > "range"filenr".txt"}}' test.txt

它还处理两个以上的部分

于 2012-07-24T09:12:10.187 回答
1

您需要做的就是将第一个范围的最后一行保存到一个变量中,然后为第二个文件重新打印该变量以及以下范围。

换句话说,由于您只是遍历每一行,因此在 BEGIN 中定义一个空变量,然后每次更新它。当您的范围结束时,您会将变量保存为最后一行。在重新开始之前将该行写到下一个文件中。

于 2012-07-24T08:29:13.120 回答
1

无法重新匹配记录,但可以选择编写模式的变体。这里第二个范围模式从包含 A 和 Z 的行匹配到包含 Z 但不包含 A 的行:

awk "/A/,/Z/ {print 1, $0} (/A/ && /Z/),(/Z/ && !/A/) {print 2, $0}"

印刷:

1 1Alorem
1 2ipsuml
1 3oremip
1 4sumZAl
2 4sumZAl
2 5oremip
2 6sumlor
2 7emZips

由于您的样本有点合成,我不知道该解决方案是否适合您的实际问题。

于 2012-07-24T09:06:16.713 回答