将回车符(\ r)转换为实际覆盖 [英] Convert carriage return (\r) to actual overwrite

查看:179
本文介绍了将回车符(\ r)转换为实际覆盖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法将回车符转换为字符串中的实际覆盖值,以便将000000000000\r1010转换为101000000000?

Is there a way to convert the carriage returns to actual overwrite in a string so that 000000000000\r1010 is transformed to 101000000000?

在基数10中有一个数字x(介于0和255之间),我想在基数2中转换此数字,添加尾随零以获得12位长的二进制表示形式,生成12个不同的数字(每个数字由以2为底的最后n个数字组成,n在1到12之间),并打印这12个数字的以10为底的表示形式.

Having a number x (between 0 and 255) in base 10, I want to convert this number in base 2, add trailing zeros to get a 12-digits long binary representation, generate 12 different numbers (each of them made of the last n digits in base 2, with n between 1 and 12) and print the base 10 representation of these 12 numbers.

  1. 使用x = 10
  2. Base 2是1010
  3. 后缀为零的101000000000
  4. 提取12个前导"数字:110101101010100101000,...
  5. 转换为基数10:125102040,...
  1. With x = 10
  2. Base 2 is 1010
  3. With trailing zeros 101000000000
  4. Extract the 12 "leading" numbers: 1, 10, 101, 1010, 10100, 101000, ...
  5. Convert to base 10: 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个字符时,我只会得到零.

4. Why it does not work

Because the variable x_base2_padded contains the whole sequence 000000000000\r1010. This can be confirmed using hexdump for instance. In the for loop, when I extract the first 12 characters, I only get zeros.

我知道我可以通过如下方式在变量上添加零来找到替代方法:

I know I can find alternative by literally adding zeros to the variable as follow:

x_base2=1010
x_base2_padded="$(printf '%s%0.*d' "${x_base2}" $((12-${#x_base2})) 0)"

或使用printfrev

x_base2=1010
x_base2_padded="$(printf '%012s' "$(printf "${x_base2}" | rev)" | rev)"

尽管这些替代方案现在可以解决我的问题并让我继续工作,但并不能真正回答我的问题.

Although these alternatives solve my problem now and let me continue my work, it does not really answer my question.

在不同的情况下可能会观察到相同的问题.例如,如果尝试连接包含回车符的多个字符串.结果可能很难预测.

The same problem may be observed in different contexts. For instance if one tries to concatenate multiple strings containing carriage returns. The result may be hard to predict.

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.

The first echo will output foo. Although you might expect the other echo to output foofoofoo..., they all output foobar.

推荐答案

以下函数overwrite对其参数进行转换,以使每次回车\r后,字符串的开头实际上都被覆盖:

The following function overwrite transforms its argument such that after each carriage return \r the beginning of the string is actually overwritten:

overwrite() {
    local segment result=
    while IFS= read -rd $'\r' segment; do
       result="$segment${result:${#segment}}"
    done < <(printf '%s\r' "$@")
    printf %s "$result"
}

示例

$ overwrite $'abcdef\r0123\rxy'
xy23ef

请注意,打印的字符串实际上是xy23ef,与echo $'abcdef\r0123\rxy'不同,echo $'abcdef\r0123\rxy'只能似乎来打印相同的字符串,但仍会打印\r,然后由终端将其解释为结果看起来相同.您可以使用hexdump确认这一点:

Note that the printed string is actually xy23ef, unlike echo $'abcdef\r0123\rxy' which only seems to print the same string, but still prints \r which is then interpreted by your terminal such that the result looks the same. You can confirm this with hexdump:

$ echo $'abcdef\r0123\rxy' | hexdump -c
0000000   a   b   c   d   e   f  \r   0   1   2   3  \r   x   y  \n
000000f
$ overwrite $'abcdef\r0123\rxy' | hexdump -c
0000000   x   y   2   3   e   f
0000006

函数overwrite还支持用参数覆盖而不是用\r分隔的段覆盖:

The function overwrite also supports overwriting by arguments instead of \r-delimited segments:

$ overwrite abcdef 0123 xy
xy23ef

要就地转换变量,请使用子外壳:myvar=$(overwrite "$myvar")

To convert variables in-place, use a subshell: myvar=$(overwrite "$myvar")

这篇关于将回车符(\ r)转换为实际覆盖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆