为何Perl中命令行传入的sprintf格式符转义字符失效?如何解决?
Perl命令行传入sprintf格式符的转义问题解决
问题原因
你在命令行传入的-fmt="%.2f\t%.1f\n"中,\t和\n会被shell当作普通的反斜杠加字母组合直接传递给Perl脚本,并没有被解析成制表符(ASCII 9)和换行符(ASCII 10)。但脚本中直接定义的$fmt="%.3f\t%.3f\n"是Perl在编译阶段就将转义序列解析为对应控制字符的,所以两者在sprintf中的表现完全不同。
解决方法
1. 让Perl重新解析转义序列
拿到从命令行提取的$fmt后,手动处理其中的转义字符:
# 处理\t和\n的简单实现 $fmt =~ s/\\n/\n/g; $fmt =~ s/\\t/\t/g;
如果需要支持更多转义序列(比如\r、\xXX等),可以用String::Escape模块简化操作:
use String::Escape qw(unbackslash); $fmt = unbackslash($fmt);
2. 让shell提前解析转义序列
不同shell有不同的写法,直接让shell把转义序列转换成控制字符再传给Perl:
- bash/zsh等Bourne系shell:使用ANSI-C风格引号
$'...'myscr.pl -fmt=$'%.2f\t%.1f\n' - csh/tcsh:借助
printf生成带控制字符的字符串set fmt = `printf "%.2f\t%.1f\n"` myscr.pl -fmt="$fmt"
3. 直接输入原始控制字符
在命令行中直接输入制表符(按Tab键)和换行符(通常按Ctrl+V再按Enter),不过这种方式操作繁琐,且在不同终端环境下可能有差异,不推荐批量使用。
内容的提问来源于stack exchange,提问作者TomR
相关产品推荐
相关产品推荐

