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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19861394/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 08:33:16  来源:igfitidea点击:

Stripping leading zeros using bash substring removal only

bash

提问by user2969118

I am aware of other ways to solve this problem that do work (and I am currently using the 'expr' method), but it bugs me that I cannot figure out how to do it with the bash built-in functions only.

我知道解决这个问题的其他方法是有效的(我目前正在使用“expr”方法),但让我烦恼的是我无法弄清楚如何仅使用 bash 内置函数来解决这个问题。

When I try to strip the leading zeros from a variable using the ${variable##remove} construct I can either only get it to remove one zero or all numbers.

当我尝试使用 ${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

I read the bash manual twice to see if I am doing it correctly, but the official documentation is sparse at best. I am aware that enabling extglob may also solve this problem but it seems like overkill for a problem as simple as this.

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

Am I missing something obvious or is it really that hard to remove one or more leading zeros from a string using bash functions only?

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

回答by devnull

The following would remove all the leading 0s from the string:

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

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

Saying "${string%%[!0]*}"would return the match after deleting the longest trailing portion of the string that satisifies [!0]*-- essentially returning the zeros at the beginning.

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

"${string#"${string%%[!0]*}"}"would remove the part returned by the above from the beginning of the string.

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



Alternatively, you could use shell arithmetic:

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

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

回答by twalberg

Yet another way, although this requires the extglob functionality being enabled:

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

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

回答by anubhava

This is also a pure BASH way of stripping leading zeroes in an one-liner:

这也是一种在单行中去除前导零的纯 BASH 方式:

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

回答by LinuxGuru

Working with minutes and hours in a cron job generator script I found that leading zeros in front of 08 & 09 cause bash to think the value is an invalid octal amount. The script could not just strip leading zeros because a single zero is still valid. The solution was to pipe to bc.

在 cron 作业生成器脚本中使用分钟和小时,我发现 08 和 09 前面的前导零导致 bash 认为该值是无效的八进制数。该脚本不能仅仅去除前导零,因为单个零仍然有效。解决方案是通过管道连接到 bc。

HOUR=09
echo $HOUR | bc
9

HOUR=0
echo $HOUR | bc
0

HOUR=14
echo $HOUR | bc
14

回答by Robin A. Meade

Delete the longest substring from the beginning of the string matching the extended glob pattern +(0), that is, one or more zeros.

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

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

prints:

印刷:

123456000

Note: this will reduce a string containing only zeros to an empty string.

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

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

prints an empty string.

打印一个空字符串。

If you want a string of zeros to reduce to a single zero, you can use arithmetic expansion together with the [base#]nform to force an arithmetic base of 10 to prevent octal interpretation:

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

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

prints:

印刷:

0