简体   繁体   中英

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

This perl one-liner swaps a token for an escape sequence.
It works as intended but only if the input is surrounded with line feeds.

ie

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

How do I avoid this issue when reading from stdin?

-n wraps your code in while (<>) {... } * (cf perldoc perlrun ). Thus, your one-liner is equivalent to:

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

See the double while (<>) {... } ? That's your issue: the first while (the one added by -n ) reads a line, then the second while (the one you wrote) reads a second line, does your s/// (on the second line), and prints this second line updated. Thus, you need a blank line before the actual line you want to process.

To fix the issue, either remove the inner while(<>) , or remove the -n flag. For instance:

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

Or,

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

Note that instead of using -n and print , you can use -p , which is the same as -n with an extra print ** at the end:

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

* For completness, note that -n adds the label LINE before the while loop ( LINE: while(<>) {... } ), although that doesn't matter in your case.

** The print added by -p is actually in a continue block after the while , although, once again, this doesn't matter in your case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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