如何在Bash及Linux命令行工具中将文本转为UTF-8编码字节?
在Bash中把文本字符串转换为UTF-8编码的字节表示
你想要的是把字符串转换成类似Python里encode('utf-8')输出的格式——ASCII字符保持原样显示,非ASCII字符则以\xXX的十六进制转义形式呈现。下面几种基于常见Linux命令行工具的方法,完全能满足你的需求:
方法1:用Perl快速实现(最贴近目标格式)
Perl对字符串的字节级处理非常灵活,一行命令就能完美模拟你想要的输出效果:
STR="Six of one, ½ dozen of the other" perl -e 'print "\x27", join("", map { ord($_) < 128 ? $_ : sprintf("\\x%02x", ord($_)) } split //, $ARGV[0]), "\x27"' "$STR"
执行后会输出:
'Six of one, \xc2\xbd dozen of the other'
这个逻辑很清晰:遍历字符串的每个字符,ASCII字符(编码值小于128)直接保留,非ASCII字符则转换成\x开头的十六进制转义格式,最后用单引号包裹结果,和你给出的示例完全一致。
方法2:用xxd生成全转义格式(适合查看所有字节)
如果你不需要保留ASCII字符的原样,想要把所有字节都转换成\xXX的形式,可以用xxd工具(几乎所有Linux发行版都预装):
STR="Six of one, ½ dozen of the other" echo -n "$STR" | xxd -p -c 256 | sed 's/../\\x&/g'
输出会是所有字符的十六进制转义串:
\x53\x69\x78\x20\x6f\x66\x20\x6f\x6e\x65\x2c\x20\xc2\xbd\x20\x64\x6f\x7a\x65\x6e\x20\x6f\x66\x20\x74\x68\x65\x20\x6f\x74\x68\x65\x72
echo -n:避免在字符串末尾添加额外的换行符xxd -p:输出纯十六进制内容(去掉默认的地址和ASCII列)xxd -c 256:确保所有内容在一行输出sed 's/../\\x&/g':把每两个十六进制字符前面加上\x前缀
方法3:用hexdump+awk实现混合格式
如果你不想用Perl,也可以组合hexdump和awk来实现和Python类似的混合输出:
STR="Six of one, ½ dozen of the other" echo -n "$STR" | hexdump -v -e '/1 "%02x "' | awk '{ for(i=1;i<=NF;i++){ hex_val = strtonum("0x"$i) if(hex_val >= 0x20 && hex_val <= 0x7E){ printf "%c", hex_val } else { printf "\\x%s", $i } } }' | sed "s/^/'/;s/$/'/"
这个命令会把可打印的ASCII字符(范围0x20到0x7E)还原成原字符,其他字符则转义成\xXX格式,最终输出和Perl方法完全一致。
内容的提问来源于stack exchange,提问作者user1717828




