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這-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添加標簽,盡管這在您的情況下無關緊要。LINEwhileLINE: while(<>) { ... }
**的print增加通過-p實際上是在continue之后的塊while,盡管再次,這件事情并沒有你的情況。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/401302.html
標籤:perl
上一篇:Perl5簽名:傳遞多個陣列
