从数字中删除前导零

3
如何在Bash/shell中将所有数字转换?
VAR=00005
VAR=00010
VAR=00601
VAR=00550

to

echo $VAR #5
echo $VAR #10
echo $VAR #601
echo $VAR #550

完全不知道怎么做 :-( - Charlie
7个回答

6
$> cat text    
00005
00010
00601
00550

$> sed -r 's/0*([0-9]*)/\1/' text    
5
10
601
550

使用 printf

$> while read n; do printf "%0d\n" $((10#$n)); done < text
5
10
601
550

注意,当数字格式期望一个数字时,内部printf命令将使用基于Bash算术规则的通用计数法。为了强制使用十进制表示,并同时删除Bash变量中的任何前导零,我们应该使用$((10#$n))


只是好奇,你的printf中的8、385和360是从哪里来的?八进制 ^_^ - Kent
我已经在答案中添加了解释。 - ДМИТРИЙ МАЛИКОВ

6

或者像这样:

kent$  echo "00005
00010
00601
00550"|awk '$0*=1'
5
10
601
550

针对您更新后的问题(带有VAR),首先,您应该使用不同的变量名称,而不是全部使用VAR。

请参考以下示例:

kent$  VAR=00601

kent$  VAR=$((VAR+0))

kent$  echo $VAR
601

编辑:

关于评论(08、09 不能工作):

这里 08、09 可以工作,可能与我的 Shell 有关。我使用的是 Zsh。我在 Bash 下测试了以下内容,它们可以工作。希望能帮到你:

在 Zsh 中:

kent$  v=08

kent$  v=$((v+0))

kent$  echo $v
8

在bash下,以下内容有效。
kent@7PLaptop:/tmp$ bash -version
GNU bash, version 3.2.48(1)-release (i486-pc-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.
kent@7PLaptop:/tmp$ v=08
kent@7PLaptop:/tmp$ v=$(sed 's/^0*//'<<< $v)
kent@7PLaptop:/tmp$ echo $v
8

VAR=08 #问题,VAR=09 #问题,结果0 - Charlie
@Charlie,请查看答案中的编辑,希望能对您有所帮助。 - Kent

2

使用extglob,您无需任何外部进程:

shopt -s extglob                       # Enable extended globbing
for i in 00005 00010 00601 00550; do
    echo ${i##+(0)}
done

这样处理数字只作为字符串,也避免了八进制解释。 - glenn jackman

2

echo $((10#${VAR}))可以做你想要的事情。

至少适用于bash和mksh。

来自bash手册

带有前导0的常量被解释为八进制数。前导“0x”或“0X”表示十六进制。否则,数字采用[base#]n的形式,其中可选基数是介于2和64之间的十进制数,表示算术基数,n是该基数中的一个数字。如果省略了base#,则使用base 10。

mksh文档在处理前导零方面更加简洁:

以"10#"为前缀强制将其解释为十进制,即使有前导零也是如此。


2
人们遇到08和09的问题是因为带有尾随零的数字被shell视为八进制。您可以尝试以下方法:
VAR="08"
let "VAR=10#${VAR}"
echo $VAR

移除前导零。


2
你的意思是前导零,而不是尾随零。 ;) - Gary Dean

-2

收件人:ДМИТРИЙ МАЛИКОВ

printf "%d\n" 0000
printf "%d\n" 0001
printf "%d\n" 0002
printf "%d\n" 0003
printf "%d\n" 0007
printf "%d\n" 0008
printf "%d\n" 0009
printf "%d\n" 0010
printf "%d\n" 0011
printf "%d\n" 0012

结果

0
1
2
3
7
0 line 8: printf: 0008: invalid octal number
0 line 9: printf: 0009: invalid octal number
8 !error - correctly 10
9 !error - correctly 11
10 !error - correctly 12

n=0015; n=$((10#$n)); printf "%d\n" $n → 15 - ДМИТРИЙ МАЛИКОВ

-2

您可以使用printf来添加或删除前导零:

$ printf "%05d\n" 5    
00005

$ printf "%d\n" 00005
5

$ printf "%010d\n" 00005
0000000005

在你的例子中使用:printf "%d\n" 00010 的结果是 8,因为它将其解析为八进制。 - allada

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接