[英]BASH: Remove leading and trailing zeroes from variable using pure bash
Case Scenerio:案例场景:
Variable or Array
var=( 002.20 20.020 20.002000 00200 20.02 .020)
for f in ${var[@]}; do echo ${f}; done
Output: 2.2 20.02 20.002 200 20.02 .02
Trying to achive this using pure bash that with help of $BASH_REMATCH capture groups尝试使用纯 bash 在 $BASH_REMATCH 捕获组的帮助下实现这一目标
Tried:
eg.
f=20.0000210
[[ $f =~ ([0-9]?\.?0?[1-9]?)(0*$) ]]
echo ${BASH_REMATCH[@]}
210 21 0
Expected:
echo ${BASH_REMATCH[@]
20.000021 0
Can anyone help with this.有人能帮忙吗。 Please.
请。 After debugging it seems bash capture groups are behaving unusually.
调试后似乎 bash 捕获组表现异常。 I dont know how BASH_REMATCH works but from online tutorials i have seen that using () we can split string into BASH_REMATCH array.
我不知道 BASH_REMATCH 是如何工作的,但是从在线教程中我看到使用 () 我们可以将字符串拆分为 BASH_REMATCH 数组。 But something odd with splitting
但是分裂有些奇怪
oK after some debugging it appears unusual behaviour is due to cygwin bash.好的,经过一些调试,出现异常行为是由于 cygwin bash。 eg var=0002;
例如 var=0002; echo ${var##0} or echo ${var##+(0)} doesnt work as expected
echo ${var##0} 或 echo ${var##+(0)} 没有按预期工作
Another way: (Another Use Case: Below Method will help splitting a string based on delimeter)另一种方式:(另一个用例:下面的方法将有助于根据分隔符拆分字符串)
var=( 002.20 20.020 20.002000 00200 20.02 .020)
for f in ${var[@]}; do
[[ $f =~ (^[^\.?]*.)(.*) ]];
INT=$(echo ${BASH_REMATCH[1]});
FRAC=$(echo ${BASH_REMATCH[2]});
echo "$f --> ${INT##+(0)}${FRAC%%+(0)}"; done
Output
002.20 --> 2.2
20.020 --> 20.02
20.002000 --> 20.002
00200 --> 200
20.02 --> 20.02
.020 --> .02
Splits and captures the Integer part and Fractional Part拆分并捕获 Integer 部分和小数部分
Capture 1 - (^[^.?] .) --> Matches beginning to decimal point which is optional in case of natural numbers and append "." Capture 1 - (^[^.?] .) --> 匹配从小数点开始,对于自然数和 append "." 是可选的。 to result
导致
Capture 2 - (. ) --> Fractional part捕获 2 - (. ) --> 小数部分
Using BASH_REMATCH[1] & [2], stores integer in INT and Fraction in FRAC使用 BASH_REMATCH[1] 和 [2],将 integer 存储在 INT 中,将 Fraction 存储在FRAC
Using string expansion remove leading "0" from INT and trailing "0" from FRAC使用字符串扩展从 INT 中删除前导“0”,从 FRAC 中删除尾随“0”
If you want to use [[ var =~ REGEX ]]
and then BASH_REMATCH
, you can do:如果你想使用
[[ var =~ REGEX ]]
然后BASH_REMATCH
,你可以这样做:
#!/bin/bash
var=( 002.20 20.020 20.002000 00200 20.02 .020)
for i in "${var[@]}"; do # loop over each element in array
if [[ $i =~ "." ]]; then # does it contain '.'?
[[ $i =~ ^0*(.*[^0]+)0*$ ]] # use regex to trim both ends
else
[[ $i =~ ^0*([^0]+.*$) ]] # otherwise trim from front.
fi
echo ${BASH_REMATCH[1]} # output result
done
Example Output示例 Output
2.2
20.02
20.002
200
20.02
.02
You can change echo
as needed to output with printf
for line control as desired.您可以根据需要将
echo
更改为 output 和printf
以根据需要进行线路控制。
$ shopt -s extglob
$ var=( 002.20 20.020 20.002000 00200 20.02 .020 )
$ for f in "${var[@]##+(0)}"; do
[[ "$f" =~ \. ]] && f="${f%%+(0)}"
printf '%s\n' "$f"
done
2.2
20.02
20.002
200
20.02
.02
Using a regular expression approach in bash:在 bash 中使用正则表达式方法:
var=(002.20 20.020 20.002000 00200 20.02 .020 20.0000210)
# regex may match an empty string also
re='^0*([1-9][0-9]*)?(\.[0-9]*[1-9])?0*$'
for n in "${var[@]}"; do
[[ $n =~ $re ]] && echo "$n => ${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
done
Output: Output:
002.20 => 2.2
20.020 => 20.02
20.002000 => 20.002
00200 => 200
20.02 => 20.02
.020 => .02
20.0000210 => 20.000021
RegEx Demo and Details正则表达式演示和详细信息
RegEx Details:正则表达式详细信息:
^
: Start ^
: 开始0*
: Match 0 or more zeroes 0*
: 匹配 0 个或多个零([1-9][0-9]*)?
: Capture group #1 (optional) to match digit 1-9 followed by 0 or more of any digits (\.[0-9]*[1-9])?
: Capture group #2 (optional) to match dot then 0 or more of any digits then digit 1-9 0*
: Match 0 or more zeroes 0*
: 匹配 0 个或多个零$
: End $
: 结束You can do it via sed.您可以通过 sed 进行操作。
$ var=( 002.20 20.020 20.002000 00200 20.02 .020)
$ for f in ${var[@]}; do echo $(echo $f|sed -r 's/^0+|0+$//g'); done
2.2
20.02
20.002
2
20.02
.02
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.