Bash dc(1)和前导零
我有一个shell脚本,我用dc(1)进行了一些计算 我需要用前导零打印一个数字;我找不到一种简单直接的方法来处理dc本身,但手册中确实提到: ZBash dc(1)和前导零,bash,sh,dc,Bash,Sh,Dc,我有一个shell脚本,我用dc(1)进行了一些计算 我需要用前导零打印一个数字;我找不到一种简单直接的方法来处理dc本身,但手册中确实提到: Z 从堆栈中弹出一个值,计算位数 它有(或字符数,如果有) 是一个字符串)并推动它 号码。a的位数计数 数字不包括任何前导字符 零,即使在 基点的右边 这意味着有一种简单而直接的方法 我知道有无数种方法可以实现这一点,我相信脚本正在与其中一种方法愉快地运行。我只是好奇;-) 这里有一个例子,虽然不雅。这将打印出带有2个前导零的999。您需要复制更多数字的
从堆栈中弹出一个值,计算位数 它有(或字符数,如果有) 是一个字符串)并推动它 号码。a的位数计数 数字不包括任何前导字符 零,即使在 基点的右边 这意味着有一种简单而直接的方法
我知道有无数种方法可以实现这一点,我相信脚本正在与其中一种方法愉快地运行。我只是好奇;-) 这里有一个例子,虽然不雅。这将打印出带有2个前导零的999。您需要复制更多数字的代码
#Push number to print on stack
999
# macro to print a zero
[[0]P]sa
# Print a zero if less than 5 digits
dZ5>a
# Print a zero if less than 4 digits
dZ4>a
# Print a zero if less than 3 digits
dZ3>a
# Print a zero if less than 2 digits
dZ2>a
# Print out number
p
尝试一下:
输入:
[lc1+dsc0nld>b]sb
[sddZdscld>bp]sa
999
12lax
3lax
输出:
000000999
999
输入:
[lc1+dsc0nld>b]sb
[sddZdscld>bp]sa
999
12lax
3lax
输出:
000000999
999
宏结束后,原始编号保留在堆栈上。使用的寄存器:a
(宏)、b
(宏)、c
(计数)、d
(数字)
说明:
宏a
执行设置,调用b
并打印原始号码
-将要输出的位数存储在寄存器sd
d
-复制原始数字并按下其数字计数dZ
-复制该计数并将其存储在寄存器dsc
c
-从寄存器ld>b
加载所需数字,如果大于计数,则调用宏d
b
-打印原始号码p
b
输出零,直到计数大于所需位数
-从寄存器lc1+
加载计数并递增c
-复制计数并将其存储回寄存器dsc
c
-输出不带换行符的零0n
-从寄存器ld>b
加载所需的数字,如果它仍然大于递增的计数,则再次循环运行宏d
,否则它将返回调用者(宏b
)a
[lclkZ+dsclknld>b]sb
[sksddZdscld>bp]sa
999 14 [ ] lax
999
[abc] 12 [-] lax
---------abc
除其他寄存器外,它还使用k
存储字符(实际上可能不止一个):
如果所需的长度数字大于原始字符串的长度,但小于两个字符串的长度(或整数倍),则填充字符串将被整体使用,因此结果可能比您要求的长度长。给定的解决方案适用于十进制数。对于十六进制(以及任何其他输入)基数使用。e、 g
c=18A; dc <<< "16i${c^^}d0r[r1+r10/d0<G]dsGx4+r-[1-[0]nlGx]sY[d0<Y]dsGxr10op"
^ radix formatted length ^ ^ leading symbol
我本来打算在
bc
中完成它,并将它所做的事情转储出去,但是GNUbc
并没有作为dc
的前端实现!顺便说一句,这可以通过一系列的堆栈交换来实现,而不需要使用那么多的寄存器,但是寄存器使它变得更容易。这是一个很好的答案——虽然比我想象的要复杂一些,但可能是最好的答案。谢谢:-)