拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 在perl中读取stdin需要在输入周围换行。如何避免?

在perl中读取stdin需要在输入周围换行。如何避免?

白鹭 - 2022-01-24 2108 0 0
MSG_OUT="<B><I>Skipping<N> all libraries and fonts...<N>"

perl -ne '%ES=("B","[1m","I","[3m","N","[m","O","[9m","R","[7m","U","[4m"); while (<>) { s/(<([BINORSU])>)/\e$ES{$2}/g; print; }'

这个 perl one-liner 将令牌交换为转义序列。
它按预期作业,但前提是输入被换行符包围。

IE

echo "\x0a${MSG_OUT}\x0a" | perl -ne '.... etc.

从标准输入读取时如何避免这个问题?

uj5u.com热心网友回复:

-n将您的代码包装在while (<>) { ... }* (cf perldoc perlrun ) 中。因此,您的单线相当于:

perl -e '
   while(<>) {
      %ES=("B","[1m","I","[3m","N","[m","O","[9m","R","[7m","U","[4m");
      while (<>) { s/(<([BINORSU])>)/\e$ES{$2}/g; print; }
   }
'

[为可读性添加了换行符。如果您愿意,可以将它们移除。]

看到双了while (<>) { ... }吗?那是你的问题:第一个while(由 增加的那个-n)读取一行,然后第二个while(你写的那个)读取第二行,做你的s///(在第二行),并列印第二行更新。因此,在要处理的实际行之前需要一个空行。

要解决此问题,请洗掉内部while(<>),或洗掉-n标志。例如:

perl -e '
   %ES=("B","[1m","I","[3m","N","[m","O","[9m","R","[7m","U","[4m");
   while (<>) { s/(<([BINORSU])>)/\e$ES{$2}/g; print; }
' 

或者,

perl -ne '
   BEGIN { %ES=("B","[1m","I","[3m","N","[m","O","[9m","R","[7m","U","[4m") };
   s/(<([BINORSU])>)/\e$ES{$2}/g; print;
'

请注意,您可以使用而不是使用-nand print-p-nprint末尾额外的**相同

perl -pe '
    BEGIN { %ES=("B","[1m","I","[3m","N","[m","O","[9m","R","[7m","U","[4m") };
    s/(<([BINORSU])>)/\e$ES{$2}/g;
'

*为完整起见,请注意回圈 ( )之前-n添加标签,尽管这在您的情况下无关紧要。LINEwhileLINE: while(<>) { ... }

**print增加通过-p实际上是在continue之后的块while,尽管再次,这件事情并没有你的情况。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *