用于查找bigrams的shell脚本

时间:2008-10-28 22:16:37

标签: shell grep nlp

我正在制作一个shell脚本来查找有问题的双字母组合。

#tokenise words
tr -sc 'a-zA-z0-9.' '\012' < $1 > out1
#create 2nd list offset by 1 word
tail -n+2 out1 > out2
#paste list together
paste out1 out2 
#clean up
rm out1 out2

唯一的问题是它将上一个句子的结尾和上一个句子的开头配对。

例如对于两句“你好世界”。和'foo bar。'我会得到一个'世界的线。富”。是否有可能用grep或其他东西过滤掉这些?

我知道我可以找到所有包含grep [。]的句号的bigrams,但也可以找到合法的双字母。

3 个答案:

答案 0 :(得分:2)

Shell脚本可以使用管道。

cat "$@" |
tr -cs "a-zA-Z0-9." '\012' |
{
old="aaa."
while read new
do
    case "$old" in
    *.) : OK;;
    *)  echo "$old $new";;
    esac
    old="$new"
done
}

代码使用cat作为数据的通用收集器 - tr是一个不接受任何文件名参数的纯过滤器。基本思想是变量old包含第一个单词,new读取新单词。当旧的以句点结束时(就像在开头一样),它不会在您的规则下形成有效的二元组。如果你想从句子结尾的双字母组中删除点,你可以使用:

 echo "$old ${new%.}"

朴素的版本(带点回声)适用于Bourne shell以及衍生品;只有${new%.}只有Korn shell和衍生工具的版本的版本 - 而不是最初的Bourne shell。

如果必须使用临时文件,则使其名称包含进程ID($$)并使用trap删除它们:

tmp=${TMPDIR:-/tmp}/bigram.$$
trap 'rm -f $tmp.?; exit 1' 0 1 2 3 13 15

...code using $tmp.1, $tmp.2, etc...

rm -f $tmp.?
trap 0

信号1是挂断(HUP),2是中断(INT),3是退出(QUIT),13是管道(PIPE),15是终止(TERM); 0是'任何退出',在这种情况下几乎是juju。在实际退出之前,请记住取消退出陷阱,如图所示。

答案 1 :(得分:2)

您可能还想浏览Ken Church's "Unix for Poets" (PDF) - 描述解决类似问题的经典之作。

答案 2 :(得分:1)

只需用以下代码替换粘贴行:

paste out1 out2 | grep -v '\..'

这将过滤掉任何包含句点的行,该句号不是行的最后一个字符。