问题
有没有一种方法可以将字符串中的回车符转换为实际的覆盖符,使得 000000000000\r1010
转换为 101000000000
?
背景
1. 初始目标:
给定一个十进制数 x
(介于 0 和 255 之间),我想将此数转换为二进制,添加尾随零以获得一个 12 位数字的二进制表示形式,生成 12 个不同的数字(每个数字由二进制中最后的 n
个数字组成,其中 n
在 1 和 12 之间),并打印这 12 个数字的十进制表示形式。
2. 示例:
- 对于
x = 10
- 二进制表示为
1010
- 添加尾随零得到
101000000000
- 提取前 12 个数字:
1
,10
,101
,1010
,10100
,101000
, ... - 转换为十进制:
1
,2
,5
,10
,20
,40
, ...
3. 我所做的(它不起作用):
x=10
x_base2="$(echo "obase=2;ibase=10;${x}" | bc)"
x_base2_padded="$(printf '%012d\r%s' 0 "${x_base2}")"
for i in {1..12}
do
t=$(echo ${x_base2_padded:0:${i}})
echo "obase=10;ibase=2;${t}" | bc
done
4. 为什么不起作用
因为变量x_base2_padded
包含整个序列000000000000\r1010
,可以使用hexdump
进行确认。在for循环中,当我提取前12个字符时,只得到了零。
5. 可选方案
我知道我可以通过在变量中添加零来找到替代方法,如下所示:
x_base2=1010
x_base2_padded="$(printf '%s%0.*d' "${x_base2}" $((12-${#x_base2})) 0)"
或者使用printf
和rev
函数在末尾填充零。
x_base2=1010
x_base2_padded="$(printf '%012s' "$(printf "${x_base2}" | rev)" | rev)"
虽然这些替代方案现在解决了我的问题,让我能够继续工作,但并没有真正回答我的问题。
相关问题
同样的问题可能会出现在不同的情境中。例如,如果尝试连接包含回车符的多个字符串,则结果可能难以预测。
str=$'bar\rfoo'
echo "${str}"
echo "${str}${str}"
echo "${str}${str}${str}"
echo "${str}${str}${str}${str}"
echo "${str}${str}${str}${str}${str}"
第一个echo
会输出foo
。尽管你可能期望另一个echo
输出foofoofoo...
,但它们都输出foobar
。
echo -e ${x:0:12}
。即使你在中间存储到一个变量中,\r
仍然存在。 - Slagt将 \r 转换为实际覆盖
”或类似的内容。从未见过像您这样写得如此好的问题 - 让我们在“关闭为 XY 问题”的危险消失后使其更加美好 :) - Socowi