You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

bash内置printf默认FORMAT是什么?如何处理混合转义ByteString?

处理混合八进制与反斜杠转义的ByteString并计算base32

我正在编写脚本,用于从获取到的键值对中的ByteString值计算base32字符串,该ByteString同时包含八进制转义序列和反斜杠转义序列。

参考脚本

#! /bin/bash

LINE='  bytes: "LaPaLaPa\363\""'

echo $LINE

K="${LINE%%: *}"
V="${LINE#*: }"
V="${V#\"}"
V="${V%\"}"      
K="${K^^}"

echo "KV='${K}'='${V}'"

FOO="$(printf "%b" "${V}")"
echo "=========================================="
printf "${FOO}" | wc -c
printf "${FOO}" | od -bc -tu1 -w24
printf "${FOO}" | base32 | tr -d "="
echo "Correct or at least wanted result!"
echo "------------------------------------------"
printf '%s' "${FOO}" | wc -c
printf '%s' "${FOO}" | od -bc -tu1 -w24
printf '%s' "${FOO}" | base32 | tr -d "="
echo "------------------------------------------"
printf '%b' "${FOO}" | wc -c
printf '%b' "${FOO}" | od -bc -tu1 -w24
printf '%b' "${FOO}" | base32 | tr -d "="
echo "------------------------------------------"
printf "%s" "${FOO}" | wc -c
printf "%s" "${FOO}" | od -bc -tu1 -w24
printf "%s" "${FOO}" | base32 | tr -d "="
echo "------------------------------------------"
printf "%b" "${FOO}" | wc -c
printf "%b" "${FOO}" | od -bc -tu1 -w24
printf "%b" "${FOO}" | base32 | tr -d "="

脚本运行输出

bytes: "LaPaLaPa\363\""
KV='  BYTES'='LaPaLaPa\363\"'
==========================================
10
0000000 114 141 120 141 114 141 120 141 363 042
          L   a   P   a   L   a   P   a 363   "
         76  97  80  97  76  97  80  97 243  34
0000012
JRQVAYKMMFIGD4ZC
Correct or at least wanted result!
------------------------------------------
11
0000000 114 141 120 141 114 141 120 141 363 134 042
          L   a   P   a   L   a   P   a 363   \   "
         76  97  80  97  76  97  80  97 243  92  34
0000013
JRQVAYKMMFIGD424EI
------------------------------------------
11
0000000 114 141 120 141 114 141 120 141 363 134 042
          L   a   P   a   L   a   P   a 363   \   "
         76  97  80  97  76  97  80  97 243  92  34
0000013
JRQVAYKMMFIGD424EI
------------------------------------------
11
0000000 114 141 120 141 114 141 120 141 363 134 042
          L   a   P   a   L   a   P   a 363   \   "
         76  97  80  97  76  97  80  97 243  92  34
0000013
JRQVAYKMMFIGD424EI
------------------------------------------
11
0000000 114 141 120 141 114 141 120 141 363 134 042
          L   a   P   a   L   a   P   a 363   \   "
         76  97  80  97  76  97  80  97 243  92  34
0000013
JRQVAYKMMFIGD424EI

初始疑问

既然第一个结果符合预期,我为什么不直接使用它呢?原因有两点:一是我认为不应该不带FORMAT字符串使用printf,按道理printf应该有默认使用的FORMAT字符串可以实现我想要的效果;二是我在处理其他ByteString时,只要不提供FORMAT字符串就会报错printf: ...: invalid format character,我推测是ByteString中包含百分号字符导致的,目前我没有可复现该问题的示例。
所以为了安全起见我必须提供FORMAT字符串对吧?但正如你所见,我尝试其他FORMAT字符串时,该示例的输出结果就出错了。
有没有可以适配所有场景的FORMAT字符串?我到现在都没有找到对应的默认值。
请问bash内置printf函数的默认FORMAT是什么?

编辑1:补充场景问题

首先非常感谢大家对我标题中的问题做了详细解答,我已经学到要仔细查看命令概要,这个问题本来我可以自行搞清楚。但我的实际问题更复杂,因为我要处理的是八进制转义和反斜杠转义混合的场景。如果我用双引号让ByteString自动插值,八进制值的插值结果会出错,它只会转义三位数字中的第一位:比如双引号中的"\363\""两个字符/字节会变成363",最终得到3、6、3和双引号共4个字符/字节,而不是八进制值363对应的字符加一个双引号。所以现在我已经了解了printf的相关规则,也知道上游输出的是非标准ByteString,请问现在最佳的、可容错的处理策略是什么?我能不能先自行转换八进制转义序列为对应字符,然后再让bash(我猜双引号之间的插值是bash处理的?)处理剩下的反斜杠转义?如果可以的话这两步要怎么实现?我之前尝试在脚本中用printf '%s'或'%b'的策略最终没有成功,我不知道要怎么实现这个需求。
总结一下,我认为正确的策略应该是第一步先把值中的八进制转义替换为对应字符,或者替换为标准反斜杠转义,这样处理后的结果放在双引号中就可以被bash正常插值了?这个思路对吗?如果对的话要怎么实现?

编辑2:临时解决方案

按照评论区Aaron的建议,我想到了一个解决方案:先用printf的FORMAT字符串%b将八进制转义序列转换为字符,之后再把结果中所有的\"替换为单个双引号"。

printf '%b' "${FOO}" | sed 's|\\"|"|g' | wc -c
printf '%b' "${FOO}" | sed 's|\\"|"|g' | od -bc -tu1 -w24
printf '%b' "${FOO}" | sed 's|\\"|"|g' | base32 | tr -d "="

运行结果:

10
0000000 114 141 120 141 114 141 120 141 363 042
          L   a   P   a   L   a   P   a 363   "
         76  97  80  97  76  97  80  97 243  34
0000012
JRQVAYKMMFIGD4ZC

这个方案在当前示例中输出了正确的结果,看起来是可行的。我希望这个方案在所有场景下都能输出正确结果……

内容的提问来源于stack exchange,提问作者Kwyrky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 09:27:03