[英]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
代替-n
和print
,这与-n
相同,最后带有一个额外的print
** :
perl -pe 'BEGIN { %ES=("B","[1m","I","[3m","N","[m","O","[9m","R","[7m","U","[4m") }; s/(<([BINORSU])>)/\e$ES{$2}/g;'
*为了完整起见,请注意-n
在while
循环( LINE: while(<>) {... }
)之前添加了 label LINE
,尽管这在您的情况下并不重要。
** -p
添加的print
实际上是在while
之后的continue
块中,尽管再一次,这在您的情况下并不重要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.