【问题标题】:perl line-mode oneliner with ARGV [duplicate]带有 ARGV 的 perl 行模式 oneliner [重复]
【发布时间】:2022-01-28 05:05:26
【问题描述】:

我经常需要运行一些 Perl 单行程序来进行快速数据操作,例如

some_command | perl -lne 'print if /abc/'

从管道读取,我不需要围绕命令 arg 文件名进行循环。如何实现下一个?

some_command | perl -lne 'print if /$ARGV[0]/' abc

这给出了错误:

Can't open abc: No such file or directory.

我知道'-n'是这样做的

while(<>) {.... }

在我的程序周围, 将 args 作为文件名,但每次都执行下一个有点不切实际

#/bin/sh
while read line
do
   some_command | perl -lne 'BEGIN{$val=shift @ARGV} print if /$val/' "$line"
done

有没有更好的方法来“进入”Perl ONE-LINER 命令行参数而不将它们解释为文件名?

【问题讨论】:

  • 为什么这么多人(不仅仅是这张海报)对“Perl one-liners”着迷?它们在工作时很棒,但它们不是强制性的;多线也可以。
  • @JonathanLeffler 嗯..这不是关于一条线与两条线。我可以用多个-e 制作多线脚本。但它是关于不使用脚本源制作不必要的文件。我很多次使用oneliners,仅仅是因为它们是直接从命令行执行一些强大的事情而无需编辑脚本文件的快速方法......也许对你来说可以为2行脚本制作一个脚本文件 - 对我来说是更快地将其直接写入命令行... ;) :)
  • @Jonathan,我管理着数千台服务器。我可以粘贴到 ssh 中的单行代码,可以粘贴到我正在传递一些日志的一系列管道命令中,可以在聊天中快速、充分地与某人交流,等等。我所做的在 bash 历史中更为明显而不是两步 vi/GET--./mysecretskript。有了单线,我很少被引诱离开我的真正任务。当其他任何东西可能不需要它们时,我很少会尝试将 Perl 模块安装到随机服务器上。而且我很少发现我已经建立了一个巨大的库,其中包含不再有用、未记录、名称神秘的脚本。
  • Perl 很谦虚。看看perldoc perlrun,或者perldoc perlvar 的一些奇怪的成员。这不是一个社区认为它太酷而不能在命令行中使用的语言。 (我猜那些人只是使用了很多 bash、sed 和 awk。)

标签: perl


【解决方案1】:

也相当短:

... | expr=abc perl -lne 'print if /$ENV{expr}/'

bash shell 中工作,但可能不适用于其他 shell。

【讨论】:

  • 偷偷摸摸。适用于基于 POSIX 的 shell(Bourne、Korn、... — 和 Bash,如前所述),但不适用于 C shell 衍生物。但这没关系;海贝壳应该留在海边,不要用于编写脚本。
  • @JonathanLeffler goode olde bourne 从什么时候开始使用基于 POSIX 的 shell?
  • @AdrianFrühwirth:这是一个简写——Bourne shell 支持这种表示法,并且是 POSIX shell 的基础。所以它应该是“基于 Bourne 的 shell”,然后列出一些变体......我不认为我会被调用。
  • @JonathanLeffler 并不是要挑剔(好吧,也许有点),我非常喜欢 csh 的评论。无意冒犯。
【解决方案2】:

一些解决方案:

perl -e'while (<STDIN>) { print if /$ARGV[0]/ }' pat

perl -e'$p = shift; while (<>) { print if /$p/ }' pat

perl -e'$p = shift; print grep /$p/, <>' pat

perl -ne'BEGIN { $p = shift } print if /$p/' pat

perl -sne'print if /$p/' -- -p=pat

PAT=pat perl -ne'print if /$ENV{PAT}/'

当然,创建一个 ORing 或所有模式的模式可能比为每个模式执行相同的命令更有意义。

【讨论】:

    【解决方案3】:

    这取决于你认为你阅读的内容,但你可以玩:

    #/bin/sh
    while read line
    do
       some_command | perl -lne "print if /$line/"
    done
    

    很明显,如果$line 可能包含斜线,这将不会发生。然后,AFAIK,你被 BEGIN 块公式困住了。

    【讨论】:

    • 使用双引号也会扩展 $_ 变量(最后一个 bash 命令的最后一个参数)。 $_ 在我的 oneliners 中很常见。 ;) 但是,无论如何,thanx 的建议 - 好点。 :)
    • 您当然必须逐个查看代码,并且在-e 的参数中在程序周围使用双引号通常比使用单引号更危险。您必须使用\$ 来保护$ 等。对于更复杂的东西,我可能会使用单引号和 BEGIN 块。
    猜你喜欢
    • 2023-04-09
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    • 1970-01-01
    • 2017-07-04
    • 1970-01-01
    • 1970-01-01
    • 2017-07-21
    相关资源
    最近更新 更多