第一个问题,所以我们走了。
我正在尝试使用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
答案 0 :(得分:1)
非常简单的TXR提取工作:
@(skip)
@ (all)
Subject A
@darea
CIP
Code
@ (and)
@ (collect)
@line
@ (until)
Subject B
@ (end)
@ (end)
@(do (put-lines line))
这假设Subject A
和CIP
以及Code
是文字文字,但DISCIPLINE AREA
会有所不同。因此,整个DISCIPLINE AREA
被捕获到变量中,而不是与文本匹配。这些细节很容易调整。例如,如果每个文件在A
中都有Subject A
的不同标识符,等等。
为什么我们匹配第一个Subject A
是因为@(skip)
是不正确的。
另外,重要的是,我们有一个@(all)
构造,它可以并行匹配两个特征。两者都必须匹配。 @(skip)
将跳过文件中的材料,直到@(all)
的两个子句找到匹配为止。
@(all)
的一个分支与多行Subject A
结构相匹配,该结构必须在正确的位置有CID
和Code
。例如,如果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
部分必须只有一部分:CIP
或Code
都可以。 TXR' fuzz
可以很好地表达这一点:
@(fuzz 1 2)
CIP
Code
这意味着"以下两行中至少有一行必须匹配"。