使用-n或-p选项时,是否可以将命令行参数传递给@ARGV? [英] Is it possible to pass command-line arguments to @ARGV when using the -n or -p options?

查看:87
本文介绍了使用-n或-p选项时,是否可以将命令行参数传递给@ARGV?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I think the title of my question basically covers it. Here's a contrived example which tries to filter for input lines that exactly equal a parameterized string, basically a 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(<>){...} 循环,菱形运算符吞噬了文件名的所有命令行参数。因此,尽管从技术上 bb 参数 did 变为 @ARGV ,但整个程序失败因为参数也是钻石操作员选择的。最终结果是,使用 -n 时无法将命令行参数传递给Perl程序。

The problem of course is that the -n option creates an implicit while (<>) { ... } loop around the code, and the diamond operator gobbles up all command-line arguments for file names. So, although technically the bb argument did get to @ARGV, the whole program fails because the argument was also picked up by the diamond operator. The end result is, it is impossible to pass command-line arguments to the Perl program when using -n.

我想我真正想要的是一个可以在代码周围循环时创建一个隐式而(< STDIN>){...} 的选项,因此可以使用命令行参数不会使用文件名,但是这种情况不存在。

I suppose what I really want is an option that would create an implicit while (<STDIN>) { ... } loop around the code, so command-line arguments wouldn't be taken for file names, but such a thing does not exist.

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

I can think of three possible workarounds:

1: BEGIN {...} 块以复制并清除 @ARGV

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

2 :同时手动编码-

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

3:

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

BEGIN {...} 块解决方案是不受欢迎的,因为它构成了单行代码中令人讨厌的上下文切换,有点冗长,并且需要弄乱特殊变量 @ARGV

The BEGIN { ... } block solution is undesirable since it constitutes a bit of a jarring context switch in the one-liner, is somewhat verbose, and requires messing with the special variable @ARGV.

我认为手动的while循环解决方案更多是非解决方案,因为它放弃了 -n 选项,关键是我希望能够在命令行参数中使用 -n 选项。

I consider the manual while-loop solution to be more of a non-solution, since it forsakes the -n option entirely, and the point is I want to be able to use the -n option with command-line arguments.

对于环境变量解可以说相同;关键是我希望能够在 -n 选项中使用命令行参数。

The same can be said for the environment variable solution; the point is I want to be able to use command-line arguments with the -n option.

更好的方法?

推荐答案

您基本上已经识别了所有这些。我至少知道,您唯一错过的一个选项是传递切换参数(而不是位置参数):

You've basically identified them all. The only one you missed, that I know of at least, is the option of passing switch arguments (instead of positional arguments):

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

您也可以使用许多getopt模块之一代替 -s 。本质上,这与在主程序循环之前在 BEGIN {} 块中操作 @ARGV 相同,但是为您做到这一点,并使它变得更干净,成为单缸纸。

You could also use one of the many getopt modules instead of -s. This is essentially doing the same thing as manipulating @ARGV in a BEGIN {} block before the main program loop, but doing it for you and making it a little cleaner for a one-liner.

这篇关于使用-n或-p选项时,是否可以将命令行参数传递给@ARGV?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆