使用perl提取特定的输出行

时间:2015-01-22 04:56:17

标签: perl sed prolog nlp output

我正在努力创建一个系统来从输入文本中推广规则。我使用reVerb创建了我的初始规则集。例如,使用以下命令[*]: $ echo "Bananas are an excellent source of potassium." | ./reverb -q | tr '\t' '\n' | cat -n

生成表格的输出:

    1  stdin
    2  1
    3  Bananas
    4  are an excellent source of
    5  potassium
    6  0
    7  1
    8  1
    9  6
   10  6
   11  7
   12  0.9999999997341693
   13  Bananas are an excellent source of potassium .
   14  NNS VBP DT JJ NN IN NN .
   15  B-NP B-VP B-NP I-NP I-NP I-NP I-NP O
   16  bananas
   17  be source of
   18  potassium

我目前正在将输出汇总到一个文件,其中包含前面的空格和数字,如上所示。

我真正追求的只是最后的简单规则,即第16,17和16行。 18.我一直在尝试创建一个脚本来提取该组件,并以Prolog子句的形式将其放到一个新文件中,即be source of(banans, potassium).

这可行吗? Prolog规则可以包含这样的空格吗?

我认为我已经锁定从reVerb获取所有输出,那么提取所需组件的最佳方法是什么?使用Perl脚本?或者也许是sed?

*后来我打算用更大的输入文件替换它,而不是单个句子。

3 个答案:

答案 0 :(得分:3)

这似乎很浪费。为什么不按原样保留标签,并使用:

$ echo "Bananas are an excellent source of potassium." \
  | ./reverb -q | cut --fields=16,17,18

是的,你可以在Prolog中有这样的规则。请参阅answer by @mat。我想你需要先知道一些Prolog,我猜。

然而,更容易使字符串成为谓词的有效名称:

  • be_source_of带下划线而不是空格
  • 'be source of'包含空格,并用单引号括起来。

您可以使用awk来完成三个字段所需的操作。例如,请参阅printf中的awk命令。或者,您可以直接从Prolog再次解析它。我觉得两者都超出了你当前问题的范围。

答案 1 :(得分:1)

sed -n 'N;N
:cycle
$!{N
   D
   b cycle
   }
s/\(.*\)\n\(.*\)\n\(.*\)/\2 (\1,\3)/p' YourFile

如果数字在输出中而不仅仅是参考,则更改上一个sed操作 s/\^ *[0-9]\{1,\} \{1,\}\(.*\)\n *[0-9]\{1,\} \{1,\}\(.*\)\n *[0-9]\{1,\} \{1,\}\(.*\)/\2 (\1,\3)/p

假设最后3行是你的"规则#34;

的来源

答案 2 :(得分:1)

关于问题的Prolog部分:

是的,Prolog事实可以包含这样的空格,并且存在合适的运算符声明。

例如:

:- op(700, fx, be).
:- op(650, fx, source).
:- op(600, fx, of).

示例查询及其结果,让您查看使用以下语法创建的术语的形状:

?- write_canonical(be source of(a, b)).
be(source(of(a,b))).

因此,使用这些运算符声明,如下所示:

be source of(a, b).

与陈述完全相同:

be(source(of(a,b)).

根据用例和其他定义,创建此类事实甚至可能是有利的(即be/1而不是source_of/2形式的事实。如果这是您需要的唯一事实,您只需写下:

source_of(a, b).

这不会创建冗余包装器并且更易于使用。

或者,正如Boris建议的那样,您可以使用'be source of'/2中的单引号。