繁体   English   中英

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

[英]Reading stdin in perl requires line feeds around input. How to avoid?

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 单行代码将令牌交换为转义序列。
它按预期工作,但前提是输入被换行符包围。

IE

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

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

-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;'

请注意,您可以使用-p代替-nprint ,这与-n相同,最后带有一个额外的print ** :

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

*为了完整起见,请注意-nwhile循环( LINE: while(<>) {... } )之前添加了 label LINE ,尽管这在您的情况下并不重要。

** -p添加的print实际上是在while之后的continue块中,尽管再一次,这在您的情况下并不重要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM