仅使用bash子字符串删除去除前导零

时间:2013-11-08 14:28:00

标签: bash

我知道其他解决这个问题的方法(我目前正在使用'expr'方法)但是它让我觉得我无法弄清楚如何使用bash构建 - 只在函数中。

当我尝试使用$ {variable ## remove}构造从变量中去掉前导零时,我可以只获取它来删除一个零或全部数字。

string="00123456"
echo "${string##0}" // Only the first 0 is removed
echo "${string##0*0}" // The whole string is removed
echo "${string#0*0}" // Works

string="01230"
echo "${string##0}" // Works
echo "${string##0*0}" // The whole string is removed
echo "${string#0*0}" // Again, the whole string is removed

我两次阅读bash手册,看看我是否正确使用,但官方文档充其量只是稀疏。我知道启用extglob也可以解决这个问题,但对于像这样简单的问题来说似乎有点过头了。

我是否遗漏了一些明显的东西,或者仅使用bash函数从字符串中删除一个或多个前导零真的很难?

5 个答案:

答案 0 :(得分:9)

以下内容将从字符串中删除所有前导0

$ string="000123456000"
$ echo "${string#"${string%%[!0]*}"}"
123456000

在删除满足"${string%%[!0]*}"的字符串的最长尾部之后,说[!0]*将返回匹配 - 基本上在开头返回零。

"${string#"${string%%[!0]*}"}"会从字符串的开头删除上面返回的部分。


或者,您可以使用shell算法:

$ string="0000123456000"
$ echo $((10#$string))
123456000

答案 1 :(得分:7)

另一种方式,虽然这需要启用extglob功能:

echo ${string/#+(0)/}

答案 2 :(得分:3)

这也是一种纯粹的NASH方式,可以在单行中剥离前导零:

string="00123456"
[[ "$string" =~ ^0*(.*)$ ]] && echo "${BASH_REMATCH[1]}"
123456

答案 3 :(得分:1)

在cron作业生成器脚本中处理分钟和小时,我发现08和09前面的前导零会导致bash认为该值是无效的八进制数。该脚本不能仅去除前导零,因为单个零仍然有效。解决的办法是通过管道传送到密送。

HOUR=09
echo $HOUR | bc
9

HOUR=0
echo $HOUR | bc
0

HOUR=14
echo $HOUR | bc
14

答案 4 :(得分:0)

从匹配扩展的glob模式+(0)的字符串的开头删除最长的子字符串,即一个或多个零。

shopt -s extglob
string="0000123456000"
echo ${string##+(0)}

打印:

123456000

注意:这会将仅包含零的字符串减少为空字符串。

shopt -s extglob
string="0000000000000"
echo ${string##+(0)}

打印一个空字符串。

如果希望将零的字符串减少为单个零,则可以将算术扩展与 [base#] n 形式一起使用,以强制算术基数为10以防止八进制解释:

string="0000000000000"
echo $((10#$string))

打印:

0