使用 -n 或 -p 选项时是不是可以将命令行参数传递给 @ARGV?

Posted

技术标签:

【中文标题】使用 -n 或 -p 选项时是不是可以将命令行参数传递给 @ARGV?【英文标题】:Is it possible to pass command-line arguments to @ARGV when using the -n or -p options?使用 -n 或 -p 选项时是否可以将命令行参数传递给 @ARGV? 【发布时间】:2017-01-07 13:36:36 【问题描述】:

我认为我的问题的标题基本上涵盖了它。这是一个人为的示例,它尝试过滤与参数化字符串完全相等的输入行,基本上是 Perlish fgrep -x

perl -ne 'chomp; print if $_ eq $ARGV[0];' bb <<<$'aa\nbb\ncc';
## Can't open bb: No such file or directory.

问题当然是-n 选项在代码周围创建了一个隐含的while (&lt;&gt;) ... 循环,并且菱形运算符吞噬了文件名的所有命令行参数。因此,虽然从技术上讲,bb 参数 确实 到达了 @ARGV,但整个程序失败了,因为该参数 被菱形运算符拾取。最终结果是,在使用-n 时,无法将命令行参数传递给 Perl 程序。

我想我真正想要的是一个选项,它会在代码周围创建一个隐式 while (&lt;STDIN&gt;) ... 循环,因此不会将命令行参数用于文件名,但这样的事情不存在。

我能想到三种可能的解决方法:

1: BEGIN ... 阻止复制并清除 @ARGV

perl -ne 'BEGIN  our @x = shift(@ARGV);  chomp; print if $_ eq $x[0];' bb <<<$'aa\nbb\ncc';
## bb

2:在单行中手动编写while循环。

perl -e 'while (<STDIN>)  chomp; print if $_ eq $ARGV[0]; ' bb <<<$'aa\nbb\ncc';
## bb

3:寻找另一种方式来传递参数,例如环境变量。

PAT=bb perl -ne 'chomp; print if $_ eq $ENVPAT;' <<<$'aa\nbb\ncc';
## bb

BEGIN ... 块解决方案是不可取的,因为它在单行中构成了一些不和谐的上下文切换,有点冗长,并且需要弄乱特殊变量 @ARGV

我认为手动 while-loop 解决方案更像是一种非解决方案,因为它完全放弃了 -n 选项,关键是我希望能够在命令行中使用 -n 选项论据。

环境变量解决方案也是如此;关键是我希望能够使用带有-n 选项的命令行参数。

有没有更好的办法?

【问题讨论】:

另见Using -e and -s switch in perl 【参考方案1】:

您基本上已经全部识别出来了。至少我知道,您唯一错过的是传递开关参数(而不是位置参数)的选项:

$ perl -sne'chomp; print if $_ eq $kwarg' -- -kwarg=bb <<<$'aa\nbb\ncc';
bb

您也可以使用众多 getopt 模块之一来代替 -s。这与在主程序循环之前的 BEGIN 块中操作 @ARGV 本质上是相同的,但它是为您完成的,并且对于单行代码来说更简洁一些。

【讨论】:

很高兴想起经常被遗忘的-s。我发现它比awk's -v option 不太方便(通常对于我的使用而言,perl 是比 awk 更好的 awk)。

以上是关于使用 -n 或 -p 选项时是不是可以将命令行参数传递给 @ARGV?的主要内容,如果未能解决你的问题,请参考以下文章

破折号和参数是不是有任何标准的命令行约定? [复制]

求助大神,命令行选项语法错误,怎么解决

java故障处理基础命令行工具

CSP 命令行选项(201403-3)

CCF 201403-3命令行选项 (STL模拟)

ETCD:配置参数