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

问题描述 投票:-1回答:2

我正在为一个单词识别程序创建几个词典,这些词典仅包含单词的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一起使用。但是,我正在寻找一种解决方案,以便可以在终端中运行命令。

bash perl for-loop substitution
2个回答
1
投票

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


0
投票

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

%ENV
© www.soinside.com 2019 - 2024. All rights reserved.