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; }'
Run Code Online (Sandbox Code Playgroud)
这个 Perl 单行代码将标记替换为转义序列。
它按预期工作,但前提是输入被换行符包围。
IE
echo "\x0a${MSG_OUT}\x0a" | perl -ne '.... etc.
Run Code Online (Sandbox Code Playgroud)
从 stdin 读取时如何避免此问题?
-n将您的代码包装在while (<>) { ... }* 中(参见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; }
}
'
Run Code Online (Sandbox Code Playgroud)
[添加换行符以提高可读性。如果您愿意,可以将它们删除。]
看到双while (<>) { ... }吗?这就是你的问题:第一个while(由 所添加的-n)读取一行,然后第二个while(你编写的)读取第二行,执行你的s///(在第二行上),并打印更新的第二行。因此,您需要在要处理的实际行之前有一个空行。
要解决此问题,请删除 insidewhile(<>)或删除该-n标志。例如:
perl -e '
%ES=("B","[1m","I","[3m","N","[m","O","[9m","R","[7m","U","[4m");
while (<>) { s/(<([BINORSU])>)/\e$ES{$2}/g; print; }
'
Run Code Online (Sandbox Code Playgroud)
或者,
perl -ne '
BEGIN { %ES=("B","[1m","I","[3m","N","[m","O","[9m","R","[7m","U","[4m") };
s/(<([BINORSU])>)/\e$ES{$2}/g; print;
'
Run Code Online (Sandbox Code Playgroud)
请注意,您可以使用,而不是使用-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;
'
Run Code Online (Sandbox Code Playgroud)
*为了完整性,请注意在循环 ( )之前-n添加标签,尽管这在您的情况下并不重要。LINEwhileLINE: while(<>) { ... }
**添加print的-p实际上是在continue后面的块中while,尽管这对于您的情况来说并不重要。