我正在制作一个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,但也可以找到合法的双字母。
答案 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 '\..'
这将过滤掉任何包含句点的行,该句号不是行的最后一个字符。