I have an array of values coming from bash which i just want to check if there are numbers or not in it. It can contain -
,
numbers and spaces at the start or end since bash is evaluating this as sting.
Since every number is represented with ,
at the end i added (,)
to the regex.
Basically i want to check if element is a number or not.
The $val
look like these.
[ [ -0.13450142741203308, -0.3073260486125946, -0.15199440717697144, -0.06535257399082184, 0.02075939252972603, 0.03708624839782715, 0.04876817390322685 ] ,[ 0.10357733070850372, 0.048686813563108444, -0.1413831114768982, -0.11497996747493744, -0.08910851925611496, -0.04536910727620125, 0.06921301782131195, 0.02547631226480007 ] ]
This is my code which looks at each value and evaluates each. However it doesn't seem to catch the cases.
re='^[[:space:]][ -]?[0-9] ([.][0-9] )?(,)[[:space:]]$'
for j in ${val[*]}
do
if ! [[ "$j" =~ $re ]] ; then
echo "Error: Not a number: $j"
fi
done
Also it needs to ignore cases which throw [
or ]
or ],
.
Any ideas how to correct this ? Thanks for the help.
CodePudding user response:
It is likely that $val
is coming to you as a string.
If you don't need to validate each number as a fully legit number, you can use shell logic to filter those things that are obviously not numbers:
val='[ [ -0.13450142741203308, -0.3073260486125946, -0.15199440717697144, -0.06535257399082184, 0.02075939252972603, 0.03708624839782715, 0.04876817390322685 ] ,[ 0.10357733070850372, 0.048686813563108444, -0.1413831114768982, -0.11497996747493744, -0.08910851925611496, -0.04536910727620125, 0.06921301782131195, 0.02547631226480007 ] ]'
for e in $val; do # PURPOSELY no quote to break on spaces
e="${e/,}"
case $e in
''|*[!0-9.\-]*) printf "'%s' is bad\n" "$e" ;;
*) printf "'%s' is good\n" "$e" ;;
esac
done
Prints:
'[' is bad
'[' is bad
'-0.13450142741203308' is good
'-0.3073260486125946' is good
'-0.15199440717697144' is good
'-0.06535257399082184' is good
'0.02075939252972603' is good
'0.03708624839782715' is good
'0.04876817390322685' is good
']' is bad
'[' is bad
'0.10357733070850372' is good
'0.048686813563108444' is good
'-0.1413831114768982' is good
'-0.11497996747493744' is good
'-0.08910851925611496' is good
'-0.04536910727620125' is good
'0.06921301782131195' is good
'0.02547631226480007' is good
']' is bad
']' is bad
That is super fast but that will fail on malformed 'numbers' such as 123-456
If you do need to filter out malformed numbers, you can use awk
for that:
echo "$val" | awk -v RS="[^0-9. -] " '($0 0==$0)'
# all legit numbers from the string...
CodePudding user response:
If you populate $val
with the given string, it's not an array, it's a string. Using it unquoted would apply word splitting to it which splits it into whitespace separated words. The spaces aren't part of the words, and some of the words (the last one in each bracketed sequence) don't end in a comma:
#! /bin/bash
val='[ [ -0.13450142741203308, -0.3073260486125946, -0.15199440717697144, -0.06535257399082184, 0.02075939252972603, 0.03708624839782715, 0.04876817390322685 ] ,[ 0.10357733070850372, 0.048686813563108444, -0.1413831114768982, -0.11497996747493744, -0.08910851925611496, -0.04536910727620125, 0.06921301782131195, 0.02547631226480007 ] ]'
re='^[ -]?[0-9] ([.][0-9] )?,?$'
for j in $val ; do
if ! [[ $j =~ $re ]] ; then
echo "Error: Not a number: $j"
fi
done
To use a bash array, declare it with round parentheses and use whitespace to separate the elements:
#! /bin/bash
val=(-0.13450142741203308 -0.3073260486125946 -0.15199440717697144 -0.06535257399082184 0.02075939252972603 0.03708624839782715 0.04876817390322685 0.10357733070850372 0.048686813563108444 -0.1413831114768982 -0.11497996747493744 -0.08910851925611496 -0.04536910727620125 0.06921301782131195 0.02547631226480007)
re='^[ -]?[0-9] ([.][0-9] )?$'
for j in "${val[@]}" ; do
if ! [[ $j =~ $re ]] ; then
echo "Error: Not a number: $j"
fi
done