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

标签 perl command-line-interface command-line-arguments

我想我的问题的标题基本上涵盖了它。这是一个人为的例子,它试图过滤完全等于参数化字符串的输入行,基本上是 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参数确实达到了@ARGV ,整个程序失败了,因为参数被菱形运算符拾取了。最终结果是,在使用 -n 时无法将命令行参数传递给 Perl 程序。 .

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

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

1: BEGIN { ... }要复制和清除的 block @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 $ENV{PAT};' <<<$'aa\nbb\ncc';
## bb

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

我认为手动 while 循环解决方案更像是一个非解决方案,因为它放弃了 -n选项,重点是我希望能够使用 -n带有命令行参数的选项。

环境变量解决方案也是如此;重点是我希望能够将命令行参数与 -n 一起使用选项。

有没有更好的办法?

最佳答案

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

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

您也可以使用许多 getopt 模块之一来代替 -s。这基本上与在主程序循环之前在 BEGIN {} block 中操作 @ARGV 做同样的事情,但是为您做这件事并使它更干净一些一行。

关于perl - 使用 -n 或 -p 选项时是否可以将命令行参数传递给 @ARGV?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39241527/

相关文章:

database - 将哈希写入文件的最佳方法

windows - 从多个 (700+) 文本文件中删除以特定单词开头的所有行

android - 如何在命令行中为新的 Android 项目构建 gradle

regex - 在文件开头插入一个新行

c++ - 命令行帮助 cl.exe 版本 12.00.8186 中出现明显错误?

bash - Bash 中 * 扩展的长度限制?

perl - 为什么Perl不让我从后缀比较中链接后缀循环?

Perl - 将 lib 与具有依赖关系的 perl 模块一起使用

golang 标志在第一个非选项后停止解析

android - 如何在 Android UIAutomator -e 命令行参数中发送带空格的文本