我正在为一个单词识别程序创建几个词典,这些词典仅包含单词的x个前声音(此后称为ngram)。因此,我从现有词典中提取所需的单词。但是,我想自动执行此操作,即找到一个ngram的所有单词(例如ngram = 3),保存它们,增加ngram(= 4)并重复该过程。代码如下:
ngrams=$(seq 3 1 9)
for ngram in $ngrams
do
cat /Lexicon/whole_lexicon.lex | perl -ne 'chomp; @tok = split(/\s+/); $ntoprint = $#tok; if ($ngram < $ntoprint) {$ntoprint = $ngram}; for ($i = 1; $i <= $ntoprint; $i++) {printf("%s\t%s\n", join("", @tok[1..$i]), join(" ", @tok[1..$i])); }' > lexicons/lex$ngram.txt
done
[不幸的是,perl无法识别$ngram
值,并且该命令无法正常工作。为了进行比较,此脚本有效:
ngram=3
cat /Lexicon/whole_lexicon.lex | perl -ne 'chomp; @tok = split(/\s+/); $ntoprint = $#tok; if (3 < $ntoprint) {$ntoprint = 3}; for ($i = 1; $i <= $ntoprint; $i++) {printf("%s\t%s\n", join("", @tok[1..$i]), join(" ", @tok[1..$i])); }' > lexicons/lex$ngram.txt
[经过研究,我现在知道我可以编写一个perl脚本,然后将变量值$ngram
传递给此脚本,在这里可以将其与@ARGV
一起使用。但是,我正在寻找一种解决方案,以便可以在终端中运行命令。
Perl不能访问shell的变量,并且shell无法更改单引号中的任何内容-这里没有“无效替换”,因为这里根本没有替换。解决方案是将值作为参数传递给Perl,或者(不太理想)让Shell将值注入Perl源,例如通过在Perl脚本的一部分周围从单引号切换到双引号。
for ngram in $(seq 3 1 9)
do
perl -ne 'BEGIN { $ngram = shift @ARGV; }
chomp;
@tok = split(/\s+/);
$ntoprint = $#tok;
if ($ngram < $ntoprint) {$ntoprint = $ngram};
for ($i = 1; $i <= $ntoprint; $i++) {
printf("%s\t%s\n", join("", @tok[1..$i]), join(" ", @tok[1..$i]));
}' "$ngram" < /Lexicon/whole_lexicon.lex > lexicons/"lex$ngram.txt"
done
这也会删除useless cat
,并修复了一个较小的引用错误。
在您的原始代码中,cat
是一个shell变量。但是将其设置为环境变量,Perl将能够通过特殊的哈希$ngram
访问它。
%ENV