如何指定“循环之前”使用“perl -ne”时的代码?

发布于 2024-10-02 04:39:31 字数 951 浏览 3 评论 0原文

使用“perl -ne”时如何指定“循环之前”代码,而不求助于 BEGIN/END 块或用实际拼写的 while 循环替换“-n”?

详细解释一下:

比如说,我有以下 Perl 代码:

use MyModule;
SETUP_CODE;
while (<>) {
    LOOP_CODE;
}
FINAL_CODE;

如何使用 perl -ne 将其替换为单行代码?

当然,循环部分由 -n 本身处理,而 FINAL_CODE 可以使用添加“} { FINAL_CODE”的技巧来完成“ 在最后;而use语句可以通过“-M”参数来处理。

因此,如果循环之前没有 SETUP_CODE,我可以编写以下内容:

perl -MMyModule -ne 'LOOP_CODE } { FINAL_CODE'

但是,我们如何在此处插入 SETUP_CODE 呢?

我唯一的想法是尝试通过 BEGIN{} 块在循环之后添加它,

perl -MMyModule -ne 'LOOP_CODE } BEGIN { SETUP_CODE } { FINAL_CODE'

但这似乎充其量是hacky。

还有其他解决方案吗?

澄清一下 - 我已经知道我可以通过拼写出while循环而不是使用“-n”来做到这一点”或使用 BEGIN/END 块(甚至可能同意从某些角度来看,执行“while”可能更好)。

我感兴趣的是是否有不同的解决方案。

How do I specify the "before-the loop" code when using "perl -ne", without resorting to either BEGIN/END blocks or replacing "-n" with actually spelled-out while loop?

To explain in detail:

Say, I have the following Perl code:

use MyModule;
SETUP_CODE;
while (<>) {
    LOOP_CODE;
}
FINAL_CODE;

How can I replace that with a one-liner using perl -ne?

Of course, the loop part is handled by the -n itself, while the FINAL_CODE can be done using a trick of adding "} { FINAL_CODE" at the end; whereas the use statement can be handled via "-M" parameter.

So, if we had no SETUP_CODE before the loop, I could write the following:

perl -MMyModule -ne 'LOOP_CODE } { FINAL_CODE'

But, how can we insert SETUP_CODE here?

The only idea I have is to try to add it after the loop via a BEGIN{} block, ala

perl -MMyModule -ne 'LOOP_CODE } BEGIN { SETUP_CODE } { FINAL_CODE'

But this seems at best hacky.

Any other solution?

Just to be clear - I already know I can do this by either spelling out the while loop instead of using "-n" or by using BEGIN/END blocks (and might even agree that from certain points of view, doing "while" is probably better).

What I'm interested in is whether there is a different solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

梦里兽 2024-10-09 04:39:32

也许有一些晦涩的方法可以用 -ne 来实现这一点,但是,是的,使用 perl -ewhile(< ;>) 你自己。

Maybe there is some obscure way to achieve this with -ne, but yeah, it is much easer just to use perl -e and code in the while(<>) yourself.

半枫 2024-10-09 04:39:32

您可以在命令行上使用多个 -e 开关。

假设测试包含

1
2
3
4

perl -e '$a=5;' -ne '$b+=$_ + $a}{print "$b\n"' test

将打印 30。

You can have multiple -e switches on the command line.

Assuming test contains

1
2
3
4

perl -e '$a=5;' -ne '$b+=$_ + $a}{print "$b\n"' test

will print 30.

墨落画卷 2024-10-09 04:39:31

无需仪式即可编写 BEGINEND 块:

$ perl -lne 'BEGIN { print "hi" }
             print if /gbacon/;
             END { print "bye" }' /etc/passwd
hi
gbacon:x:700:700:Greg Bacon,,,:/home/gbacon:/bin/bash
bye

Write BEGIN and END blocks without ceremony:

$ perl -lne 'BEGIN { print "hi" }
             print if /gbacon/;
             END { print "bye" }' /etc/passwd
hi
gbacon:x:700:700:Greg Bacon,,,:/home/gbacon:/bin/bash
bye
流云如水 2024-10-09 04:39:31

将额外的代码隐藏到 -M 选项

perl -M'Module;SETUP CODE' -ne 'LOOP CODE'

$ perl -MO=Deparse -M'MyModule;$SETUP=1' -ne '$LOOP=1}{$FINAL=1'
use MyModule;
$SETUP = 1;
LINE: while (defined($_ = <ARGV>)) {
    $LOOP = 1;
}
{
    $FINAL = 1;
}
-e syntax OK

Sneak your extra code into the -M option

perl -M'Module;SETUP CODE' -ne 'LOOP CODE'

 

$ perl -MO=Deparse -M'MyModule;$SETUP=1' -ne '$LOOP=1}{$FINAL=1'
use MyModule;
$SETUP = 1;
LINE: while (defined($_ = <ARGV>)) {
    $LOOP = 1;
}
{
    $FINAL = 1;
}
-e syntax OK
灯角 2024-10-09 04:39:31

将额外的代码放入模块中并使用 -M。这将在循环之前运行。

您甚至可以通过 $ENV{PERL5OPT} 潜入一些东西,尽管开关非常有限;例如,没有 -e-E

我想如果你真的愿意的话,你也可以用 $ENV{PERL_ENCODING} 做一些离谱的事情。

这就是Acme:: 的全部领域。 不要这样做。 ☹

编辑:唯一喜欢的解决方案是非常没有创意且完全简单的INIT{}

Put your extra code in a module and use ‑M. That’ll run before the loop.

You might even be able to sneak something in via $ENV{PERL5OPT}, although the switches are pretty limited; no ‑e or ‑E, for example.

I suppose you could do something outrageous with $ENV{PERL_ENCODING} too, if you really wanted to.

This is all Acme:: territory. Please don’t. ☹

EDIT: The only solution I much like is the very uncreative and completely straightforward INIT{}.

兔姬 2024-10-09 04:39:31

删除 -n 并添加 while (<>) { ... }
什么?它比 BEGIN 更短、更直接。

Remove the -n and add while (<>) { ... }.
What? It's shorter and more straightforward than the BEGIN thing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文