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;
'
请注意,您可以使用,而不是使用-n
and print
,-p
这-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
添加标签,尽管这在您的情况下无关紧要。LINE
while
LINE: while(<>) { ... }
**的print
增加通过-p
实际上是在continue
之后的块while
,尽管再次,这件事情并没有你的情况。
0 评论