awk用于选择非标准格式文档中的文本

时间:2015-07-07 02:52:38

标签: text awk block repeat

第一个问题,所以我们走了。

我正在尝试使用awk从40个文档中提取选择的文本。每个文档都有唯一的格式(没有相同的长度,标题不同等)。

我想要做的是编写一个自适应awk程序,我可以在文本之间轻松更改。我已经列出了所有文本中最具代表性的一部分。有了一个很好的答案,我可以适应其余的。我的技能很好,但对于我遇到的一些问题还不够好。

基本上,我正在使用准系统一个衬垫:     awk'/ Subject A / {p = 1} / CIP / {print; p = 0} p'sample.txt

在此

Subject A
DISCIPLINE AREA
CIP
Code

random material

Subject A #note that this is the second instance of Subject A
UN

Description of Subject

Subject B
DISCIPLINE AREA
CIP
Code
etc...

我得到了结果:

The second instance of Subject A
all the way through to
Subject B

我想做什么: 在“主题A”的第一个实例之间打印/输出所有材料,包括“主题A”的第二个实例,并在“主题B”之前结束。

问题: 有数百个这样的重复,唯一不变的是一个主题,学科领域和一个块中的cip。我无法获得该块的完整描述,因为它从第二个主题B开始。

我见过很多解决方案,但我不能让他们在我的工作:(

任何参赛者?

对不起它太长了但我不得不解释一下。 -R

1 个答案:

答案 0 :(得分:1)

非常简单的TXR提取工作:

@(skip)
@  (all)
Subject A
@darea
CIP
Code
@  (and)
@    (collect)
@line
@    (until)
Subject B
@    (end)
@  (end)
@(do (put-lines line))

这假设Subject ACIP以及Code是文字文字,但DISCIPLINE AREA会有所不同。因此,整个DISCIPLINE AREA被捕获到变量中,而不是与文本匹配。这些细节很容易调整。例如,如果每个文件在A中都有Subject A的不同标识符,等等。

为什么我们匹配第一个Subject A是因为@(skip)是不正确的。

另外,重要的是,我们有一个@(all)构造,它可以并行匹配两个特征。两者都必须匹配。 @(skip)将跳过文件中的材料,直到@(all)的两个子句找到匹配为止。

@(all)的一个分支与多行Subject A结构相匹配,该结构必须在正确的位置有CIDCode。例如,如果CIP没有出现或在同一行后面跟着垃圾,或者Code后面没有,那么就没有匹配。

与此同时,我们有另一个模式匹配子句(由@(and)分隔,其中@(collect) which gathers lines into a list until just before主题B`。

@(all)的两个分支匹配时,我们所要做的就是转储收集的行列表。

@(collect)子句中匹配的变量会自动变为字符串列表。要输出我们只使用put-lines

执行命令

$ txr extract.txr data
Subject A
DISCIPLINE AREA
CIP
Code

random material

Subject A #note that this is the second instance of Subject A
UN

Description of Subject

因此,您可以看到这是一种强大的方法,其中跨多行文本的多个模式协同工作以避免误报,但六个月后很容易阅读代码并仍然了解它正在寻找什么和提取

假设Subject部分必须只有一部分:CIPCode都可以。 TXR' fuzz可以很好地表达这一点:

@(fuzz 1 2)
CIP
Code

这意味着"以下两行中至少有一行必须匹配"。