How to convert string to integer in UNIX

前端 未结 5 735
广开言路
广开言路 2020-12-25 11:03

I have d1=\"11\" and d2=\"07\". I want to convert d1 and d2 to integers and perform d1-d2. How do I do this

相关标签:
5条回答
  • 2020-12-25 11:18

    An answer that is not limited to the OP's case

    The title of the question leads people here, so I decided to answer that question for everyone else since the OP's described case was so limited.

    TL;DR

    I finally settled on writing a function.

    1. If you want 0 in case of non-int:
    int(){ printf '%d' ${1:-} 2>/dev/null || :; }
    
    1. If you want [empty_string] in case of non-int:
    int(){ expr 0 + ${1:-} 2>/dev/null||:; }
    
    1. If you want find the first int or [empty_string]:
    int(){ expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null||:; }
    
    1. If you want find the first int or 0:
    # This is a combination of numbers 1 and 2
    int(){ expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null||:; }
    

    If you want to get a non-zero status code on non-int, remove the ||: (aka or true) but leave the ;

    Tests

    # Wrapped in parens to call a subprocess and not `set` options in the main bash process
    # In other words, you can literally copy-paste this code block into your shell to test
    ( set -eu;
        tests=( 4 "5" "6foo" "bar7" "foo8.9bar" "baz" " " "" )
        test(){ echo; type int; for test in "${tests[@]}"; do echo "got '$(int $test)' from '$test'"; done; echo "got '$(int)' with no argument"; }
    
        int(){ printf '%d' ${1:-} 2>/dev/null||:; };
        test
    
        int(){ expr 0 + ${1:-} 2>/dev/null||:; }
        test
    
        int(){ expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null||:; }
        test
    
        int(){ printf '%d' $(expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null)||:; }
        test
    
        # unexpected inconsistent results from `bc`
        int(){ bc<<<"${1:-}" 2>/dev/null||:; }
        test
    )
    

    Test output

    int is a function
    int ()
    {
        printf '%d' ${1:-} 2> /dev/null || :
    }
    got '4' from '4'
    got '5' from '5'
    got '0' from '6foo'
    got '0' from 'bar7'
    got '0' from 'foo8.9bar'
    got '0' from 'baz'
    got '0' from ' '
    got '0' from ''
    got '0' with no argument
    
    int is a function
    int ()
    {
        expr 0 + ${1:-} 2> /dev/null || :
    }
    got '4' from '4'
    got '5' from '5'
    got '' from '6foo'
    got '' from 'bar7'
    got '' from 'foo8.9bar'
    got '' from 'baz'
    got '' from ' '
    got '' from ''
    got '' with no argument
    
    int is a function
    int ()
    {
        expr ${1:-} : '[^0-9]*\([0-9]*\)' 2> /dev/null || :
    }
    got '4' from '4'
    got '5' from '5'
    got '6' from '6foo'
    got '7' from 'bar7'
    got '8' from 'foo8.9bar'
    got '' from 'baz'
    got '' from ' '
    got '' from ''
    got '' with no argument
    
    int is a function
    int ()
    {
        printf '%d' $(expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null) || :
    }
    got '4' from '4'
    got '5' from '5'
    got '6' from '6foo'
    got '7' from 'bar7'
    got '8' from 'foo8.9bar'
    got '0' from 'baz'
    got '0' from ' '
    got '0' from ''
    got '0' with no argument
    
    int is a function
    int ()
    {
        bc <<< "${1:-}" 2> /dev/null || :
    }
    got '4' from '4'
    got '5' from '5'
    got '' from '6foo'
    got '0' from 'bar7'
    got '' from 'foo8.9bar'
    got '0' from 'baz'
    got '' from ' '
    got '' from ''
    got '' with no argument
    

    Note

    I got sent down this rabbit hole because the accepted answer is not compatible with set -o nounset (aka set -u)

    # This works
    $ ( number="3"; string="foo"; echo $((number)) $((string)); )
    3 0
    
    # This doesn't
    $ ( set -u; number="3"; string="foo"; echo $((number)) $((string)); )
    -bash: foo: unbound variable
    
    0 讨论(0)
  • 2020-12-25 11:18

    Use this:

    #include <stdlib.h>
    #include <string.h>
    
    int main()
    {
        const char *d1 = "11";
        int d1int = atoi(d1);
        printf("d1 = %d\n", d1);
        return 0;
    }
    

    etc.

    0 讨论(0)
  • 2020-12-25 11:19
    let d=d1-d2;echo $d;
    

    This should help.

    0 讨论(0)
  • 2020-12-25 11:26

    The standard solution:

     expr $d1 - $d2
    

    You can also do:

    echo $(( d1 - d2 ))
    

    but beware that this will treat 07 as an octal number! (so 07 is the same as 7, but 010 is different than 10).

    0 讨论(0)
  • 2020-12-25 11:26

    Any of these will work from the shell command line. bc is probably your most straight forward solution though.

    Using bc:

    $ echo "$d1 - $d2" | bc
    

    Using awk:

    $ echo $d1 $d2 | awk '{print $1 - $2}'
    

    Using perl:

    $ perl -E "say $d1 - $d2"
    

    Using Python:

    $ python -c "print $d1 - $d2"
    

    all return

    4
    
    0 讨论(0)
提交回复
热议问题