LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-26-2022, 01:27 PM   #1
Skaperen
Senior Member
 
Registered: May 2009
Location: center of singularity
Distribution: Xubuntu, Ubuntu, Slackware, Amazon Linux, OpenBSD, LFS (on Sparc_32 and i386)
Posts: 2,689
Blog Entries: 31

Rep: Reputation: 176Reputation: 176
BASH: test for a decimal number


what is the best way, in bash, to test if a string is a valid decimal number? hexadecimal number? octal? binary? a valid IP address? IPv4? IPv6? i would like to see one command ways.

i am thinking about making a tool to do this for bash scripting even though i have shifted over to Python for such things.
 
Old 04-26-2022, 02:08 PM   #2
Grobe
Member
 
Registered: Aug 2019
Location: Close to north
Distribution: Fedora
Posts: 117

Rep: Reputation: Disabled
Without having a ready-made solution, I'd suggest regular expression tests.
 
Old 04-27-2022, 01:16 AM   #3
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,369

Rep: Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753
You could possibly use tricks from https://wiki.bash-hackers.org/syntax/pe to eg strip out any 'valid' chars and see if anything it left - if there is, that wasn't a valid decimal (or whatever)..
 
Old 04-27-2022, 03:25 AM   #4
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,041

Rep: Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348
Quote:
Originally Posted by Skaperen View Post
what is the best way, in bash, to test if a string is a valid decimal number? hexadecimal number? octal? binary? a valid IP address? IPv4? IPv6? i would like to see one command ways.

i am thinking about making a tool to do this for bash scripting even though i have shifted over to Python for such things.
Do not do that. bash is not really capable/suitable to do decimal or hexadecimal (octal/binary) calculations. Obviously it can be implemented (in pure bash), but it will be extremely slow/inefficient - and therefore more or less useless.
 
Old 04-29-2022, 10:32 PM   #5
rnturn
Senior Member
 
Registered: Jan 2003
Location: Illinois (SW Chicago 'burbs)
Distribution: openSUSE, Raspbian, Slackware. Previous: MacOS, Red Hat, Coherent, Consensys SVR4.2, Tru64, Solaris
Posts: 2,818

Rep: Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550
Quote:
Originally Posted by chrism01 View Post
You could possibly use tricks from https://wiki.bash-hackers.org/syntax/pe to eg strip out any 'valid' chars and see if anything it left - if there is, that wasn't a valid decimal (or whatever)..
That might work for some of the more simple checks. But a one liner to tell you that whether or not "300.300.300.300" (all valid characters) is a valid IPv4 address? Not likely. Someone told me not long ago that the regex for accurately validating an IPv6 address in all its wierd and wacky forms ("Standard, and Mixed, and Compressed... Oh my!") is several thousand characters long. That'd be a heck of a one-liner.
 
Old 04-30-2022, 07:45 AM   #6
teckk
LQ Guru
 
Registered: Oct 2004
Distribution: Arch
Posts: 5,152
Blog Entries: 6

Rep: Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835
I'll play briefly

checkip4.sh
Code:
#!/usr/bin/bash

#Validate IP4 example

ips=(
    8.8.8.8
    a.b.c.d
    192.168.1.1
    0.0.0.0
    255.255.255.255
    255.255.255.256
    256.255.255.255
    192.168.0.1
    192.168.0
    127.0.0.1
    1234.123.123.123
    )

valid_ip() {
    local  ip=$1
    local  stat=1

    if [[ "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        OIFS=$IFS
        IFS='.'
        ip=($ip)
        IFS=$OIFS
        [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
        stat=$?
    fi
    return $stat
}

for ip in "${ips[@]}"; do
    if valid_ip "$ip"; then 
        stat='good'
    else 
        stat='bad'; fi
    printf "%-20s: %s\n" "$ip" "$stat"
done
 
1 members found this post helpful.
Old 04-30-2022, 05:18 PM   #7
Skaperen
Senior Member
 
Registered: May 2009
Location: center of singularity
Distribution: Xubuntu, Ubuntu, Slackware, Amazon Linux, OpenBSD, LFS (on Sparc_32 and i386)
Posts: 2,689

Original Poster
Blog Entries: 31

Rep: Reputation: 176Reputation: 176
Quote:
Originally Posted by rnturn View Post
That might work for some of the more simple checks. But a one liner to tell you that whether or not "300.300.300.300" (all valid characters) is a valid IPv4 address? Not likely. Someone told me not long ago that the regex for accurately validating an IPv6 address in all its wierd and wacky forms ("Standard, and Mixed, and Compressed... Oh my!") is several thousand characters long. That'd be a heck of a one-liner.
how can you test for write access to a file in one line? the "test -w" command can do that and give a result in the exit status. the reason i am asking this is to discover if it is worthwhile to make a new command to do such a test. so maybe "testnum -x $myhex" could do that.

note that bash can convert hexadecimal and octal to decimal in its arithmetic operation. i don't know how to trap the errors the a bad digit could cause. maybe someone here does.

i have written tests for IP4 and IP6 in Python as functions that let the C library do the hard work. testing numbers in various bases from 2 to 36 or beyond should be trivial in Python to make a command script. i'm thinking of:
Code:
testnum -b num
testnum -o num
testnum -d num
testnum -x num
testnum -4 addr
testnum -6 addr
 
Old 04-30-2022, 06:07 PM   #8
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,784

Rep: Reputation: 5937Reputation: 5937Reputation: 5937Reputation: 5937Reputation: 5937Reputation: 5937Reputation: 5937Reputation: 5937Reputation: 5937Reputation: 5937Reputation: 5937
Quote:
how can you test for write access to a file in one line? the "test -w" command can do that and give a result in the exit status.
test is a shell built in function as well as a GNU core utility. The latter is a separate compiled program and works because that is how the utility was written. If it is worthwhile for you to have such a utility then who cares about what others think...

bash basically treats all variables as strings until you use them in a particular function or test which is why I assume that regex was suggested above. You could probably write your utility in just about any language but bash might not be the best choice.
 
Old 04-30-2022, 07:06 PM   #9
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,784

Rep: Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214
Quote:
Originally Posted by michaelk View Post
You could probably write your utility in just about any language but bash might not be the best choice.
I would also recommend against trying to use Ook (for any purpose, for that matter). But hey, Ook is Turing-complete, so it's possible, in theory.
 
Old 05-01-2022, 02:20 AM   #10
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,041

Rep: Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348
Quote:
Originally Posted by Skaperen View Post
how can you test for write access to a file in one line? the "test -w" command can do that and give a result in the exit status. the reason i am asking this is to discover if it is worthwhile to make a new command to do such a test. so maybe "testnum -x $myhex" could do that.
You can definitely implement it and put it into bash [source code] if you wish.

Quote:
Originally Posted by Skaperen View Post
note that bash can convert hexadecimal and octal to decimal in its arithmetic operation. i don't know how to trap the errors the a bad digit could cause. maybe someone here does.
As you wrote a test (or convert) function will return 0 (as exit code) on success and return non-zero otherwise. What else do you need?

Quote:
Originally Posted by Skaperen View Post
i have written tests for IP4 and IP6 in Python as functions that let the C library do the hard work. testing numbers in various bases from 2 to 36 or beyond should be trivial in Python to make a command script. i'm thinking of:
Code:
testnum -b num
testnum -o num
testnum -d num
testnum -x num
testnum -4 addr
testnum -6 addr
Additionally -p (positive), -n (negative), -f (float), -i (integer). What about scientific notations, complex numbers and others?
 
Old 05-01-2022, 08:57 AM   #11
teckk
LQ Guru
 
Registered: Oct 2004
Distribution: Arch
Posts: 5,152
Blog Entries: 6

Rep: Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835Reputation: 1835
Quote:
i don't know how to trap the errors the a bad digit could cause. maybe someone here does.
If I understand you.
Code:
#!/usr/bin/bash

#Test for hex or numeric example

n=(12 31 ae 1a 16 b5 ff 1f 12 24 2c AA Ac 1C 39 28 1f 3d 10 29 a1 A2 a3)

is_numeric() {
    case "$i" in
        "" | *[![:digit:]]* | 0[[:digit:]]* ) return 1;;
    esac
}

is_hex() {
    case "$i" in
        "" | *[![:xdigit:]]* ) return 1;;
    esac
}

for i in "${n[@]}"; do
    if is_numeric; then
        echo ""$i" is numeric"
    elif is_hex; then
        echo ""$i" is hex"
    fi
done
 
Old 05-01-2022, 11:30 AM   #12
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,784

Rep: Reputation: 5937Reputation: 5937Reputation: 5937Reputation: 5937Reputation: 5937Reputation: 5937Reputation: 5937Reputation: 5937Reputation: 5937Reputation: 5937Reputation: 5937
I think something more like...
Code:
#!/bin/bash
while getopts ":n:b:o:d:n:x:" options; do
   case "${options}" in
     n)
        mynum=${OPTARG}
        if ! [[ "$mynum" =~ ^[0-9]+$ ]] ; then
            echo "is not number"
            exit 1
        fi    
     ;;
     d)
        mynum=${OPTARG}
        if ! [[ "$mynum" =~ ^[+-]?[0-9]+([.,][0-9]+)?$ ]] ; then
            echo "not a decimal"
            exit 1
        fi 
    ;; 
    x)
        mynum=${OPTARG}
        if  ! [[ "$mynum" =~ ^[A-Fa-f0-9]+$ ]] ; then
            echo "is not hex"
            exit 1
        fi 
    ;;        
   esac
done
It depends on what or if you use some standard notation for octal or hex numbers...

Last edited by michaelk; 05-01-2022 at 11:37 AM.
 
Old 05-01-2022, 11:50 PM   #13
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,041

Rep: Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348
Quote:
Originally Posted by michaelk View Post
I think something more like...
Code:
#!/bin/bash
while getopts ":n:b:o:d:n:x:" options; do
   case "${options}" in
     n)
        mynum=${OPTARG}
        if ! [[ "$mynum" =~ ^[0-9]+$ ]] ; then
            echo "is not number"
            exit 1
        fi
It depends on what or if you use some standard notation for octal or hex numbers...
regex is extremely slow in bash, also would be faster if implemented as function (and sourced)
Code:
function isint() {
    local mynum="$1"
    local a="${mynum//[0123456789]/}"
    [[ ${#a} -eq 0 ]]
}
function ishex() {
    local mynum="$1,,"
    local a="${mynum//[0123456789abcdef]/}"
    [[ ${#a} -eq 0 ]]
}
but you need to check additionally the decimal point, +- or any other "requirements". (not tested)
 
Old 05-02-2022, 08:37 AM   #14
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,784

Rep: Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214Reputation: 2214
How about numbers with an explicit base:
Code:
$ echo $((10#1234))
1234
$ echo $((0xbeef))
48879
$ echo $((21#20))
42
 
Old 05-03-2022, 02:50 PM   #15
Skaperen
Senior Member
 
Registered: May 2009
Location: center of singularity
Distribution: Xubuntu, Ubuntu, Slackware, Amazon Linux, OpenBSD, LFS (on Sparc_32 and i386)
Posts: 2,689

Original Poster
Blog Entries: 31

Rep: Reputation: 176Reputation: 176
Quote:
Originally Posted by pan64 View Post
bash is not really capable/suitable to do decimal or hexadecimal (octal/binary) calculations.
it can, at least, do conversion from hexadecimal or octal to decimal.
Code:
lt2a/forums/1 /home/forums 13> bash -c 'echo $((0x11111111));echo $((011111111))'
286331153
2396745
lt2a/forums/1 /home/forums 14>
Quote:
Originally Posted by pan64 View Post
Obviously it can be implemented (in pure bash), but it will be extremely slow/inefficient - and therefore more or less useless.
agreed. but if i can trap errors correctly, maybe trying a conversion could be a way to test for validity without all that slow/inefficient.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Arithmetic operation in bash script, multiply by decimal number, how? postcd Linux - General 5 06-28-2021 04:21 PM
4gig file trying to replace decimal number A with decimal number B tasdca Linux - Software 5 03-26-2015 05:51 PM
Number of bits (field in general) required to store decimal number srinietrx Programming 7 11-04-2014 07:13 AM
[SOLVED] BC provides incorrect decimal results, but only on the last two decimal places... standard_output Linux - Newbie 4 06-27-2012 05:30 PM
convert number (not hex) into Decimal number drManhattan Programming 10 10-15-2011 08:53 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:07 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration