如何在Perl中修复错误的变量替换

我正在为一个单词识别程序创建几个词典,这些词典仅包含单词的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",@tok[1..$i])); }' > lexicons/lex$ngram.txt

经过研究,我现在知道我可以编写一个perl脚本,然后将变量值$ngram传递给该脚本,在这里我可以将其与@ARGV一起使用。但是,我正在寻找一种解决方案,以便可以在终端中运行命令。

hy124513 回答:如何在Perl中修复错误的变量替换

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,并修复了一个较小的引用错误。

,

在您的原始代码中,$ngram是一个shell变量。但是将其设置为环境变量,Perl将能够通过特殊的哈希%ENV访问它。

export ngram       # upgrade $ngram from shell to environment variable
for ngram in $ngrams
do

    perl -ne 'chomp; @tok = split(/\s+/); $ntoprint = $#tok; 
          if ($ENV{ngram} < $ntoprint) {$ntoprint = $ENV{ngram}};
          for ($i = 1; $i <= $ntoprint; $i++) {
              printf("%s\t%s\n",@tok[1..$i]));
          }' < /Lexicon/whole_lexicon.lex > lexicons/lex$ngram.txt

done
本文链接:https://www.f2er.com/3142848.html

大家都在问