运行 perl 脚本中的 perl 脚本使用命名参数

Run perl script within perl script using named arguments

我正在编写一个 Perl 程序,它必须 运行 一些 Perl 脚本在不同的输入上多次。

我尝试使用的脚本是 count.plstatistic.pl 来自 Text::NSP。 这些不是我自己写的,所以我不想尝试将它们重构到一个模块中。

我看了 a similar question 并想出了如何使用 system 方法 IPC::System::Simple.

但是,我想使用 count.plstatistic.pl 中的命名参数。我还没有想出如何做到这一点。这是我当前的代码:

system($^X, token="valid_tokens.txt", "/Users/cat/perl5/bin/statistic.pl", "ll.pm", "lab01_jav_bigrams.ll",
"/Users/cat/Perl_scripts/214_Final_project/lab01_java_bigrams.cnt");

这是我得到的错误:

Can't modify constant item in scalar assignment at ngram_calcs.PL line 22, near ""valid_tokens.txt"," Bareword "token" not allowed while "strict subs" in use at ngram_calcs.PL line 22.

值得注意的是,在我添加命名参数之前,代码运行良好。如何为 IPC::System::Simple 提供命名参数?或者有更好的方法来做我想做的事情吗?

编辑:谢谢,Haukex,我确实有错误的参数,使用“--token=valid_tokens.txt”有效。

虽然问题解决了,但我会分享更多的上下文,让其他看到的人受益。在命令行上我会输入:

count.pl -token validtokens.txt lab01_java_bigrams.cnt Users/cat/CS214/lab01_java.txt
statistic.pl -score 6.63 ll.pm lab01_java.ll lab01_java_bigrams.cnt

这是正确的 perl 代码:

system($^X, "/Users/cat/perl5/bin/count.pl", "--token=valid_tokens.txt", "lab01_java_bigrams.cnt", $filename);
system($^X, "/Users/cat/perl5/bin/statistic.pl", "--score=6.63", "ll.pm", "lab01_java_bigrams.ll", "/Users/cat/Perl_scripts/214_Final_project/lab01_java_bigrams.cnt");

你能试试这个格式吗?

system('/Users/cat/perl5/bin/statistic.pl  --token valid_tokens.txt  ll.pm  lab01_jav_bigrams.ll  /Users/cat/Perl_scripts/214_Final_project/lab01_java_bigrams.cnt');

但我检查了 CPAN 模块的来源,似乎 tokencount.pl 的一个选项,但不是 statistic.pl

无论如何,可以指定类似于--token valid_tokens.txt的任何选项。

希望对您有所帮助!

假设您对 statistic.pl 的调用大致正确,system 的参数需要如下所示

system($^X,
    "/Users/cat/perl5/bin/statistic.pl",
    qq/token="valid_tokens.txt"/,
    "ll.pm",
    "lab01_jav_bigrams.ll",
    "/Users/cat/Perl_scripts/214_Final_project/lab01_java_bigrams.cnt"
);

即所有参数都属于程序文件之后,整个命名参数字符串必须用引号括起来

请阅读下面 haukex 的评论,了解另一个潜在的错误

我对您的 system 调用感到困惑。查看 statistic.pl and count.pl, it seems that only the latter takes a token argument, but you don't seem to be running count.pl. $^X 的来源是当前的 运行 Perl 解释器,通常后面跟着 解释器 的任何参数,然后是脚本的名称,然后脚本 的任何参数 ,因此将 token 参数放在脚本之前对我来说没有意义。

例如,如果您试图将 count.pl 的输出通过管道传输到 statistic.pl,则您必须进一步解释,因为那是 IPC::System::Simple can't handle (at least not without invoking the shell, which I would recommend against), and you'd need a more advanced module like IPC::Run 的事情。现在,我假设您想将 token 参数传递给支持它的脚本。

命令行参数只是字符串。如果从 *NIX shell 你要写类似 ./script.pl token="test file" foo bar 的东西,那么 shell 将接管白色 space 的解释] 并引用。 script.pl 会得到像 ("token=test file", "foo", "bar") 这样的字符串列表(注意 shell 如何处理那里的引号)。

此字符串列表是您需要传递给 system 的内容,不一定 与您在命令行中键入的内容相同。由被调用程序来解释这些参数。你是运行的两个脚本使用Getopt::Long,命名参数需要以两个破折号为前缀。所以这样的事情应该有效:

system($^X, "/Users/cat/perl5/bin/count.pl", "--token=valid_tokens.txt", ...);

至于如何传递包含引号等特殊字符的参数(在这种情况下不适用),Perl 中有多种语法:"--foo=\"bar\""'--foo="bar"'q{--foo="bar"}(参见 Quote and Quote-like Operators)。