GNU/Linux >> Znalost Linux >  >> Linux

Jak převést řetězec na celé číslo v UNIXu

Standardní řešení:

 expr $d1 - $d2

Můžete také:

echo $(( d1 - d2 ))

ale mějte na paměti, že to bude řešit 07 jako osmičkové číslo! (takže 07 je stejný jako 7 , ale 010 se liší od 10 ).


Kterýkoli z nich bude fungovat z příkazového řádku shellu. bc je však pravděpodobně vaším nejpřímějším řešením.

Použití bc:

$ echo "$d1 - $d2" | bc

Pomocí awk :

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

Pomocí perl :

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

Pomocí Python :

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

vše vrátit

4

Odpověď, která není omezena na případ OP

Název otázky vede lidi sem, takže jsem se rozhodl odpovědět na tuto otázku všem ostatním, protože popisovaný případ OP byl tak omezený.

TL;DR

Nakonec jsem se rozhodl napsat funkci.

  1. Pokud chcete 0 v případě non-int:
int(){ printf '%d' ${1:-} 2>/dev/null || :; }
  1. Pokud chcete [prázdný_řetězec] v případě non-int:
int(){ expr 0 + ${1:-} 2>/dev/null||:; }
  1. Pokud chcete najít první int nebo [empty_string] :
int(){ expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null||:; }
  1. Pokud chcete najít první int nebo 0:
# This is a combination of numbers 1 and 2
int(){ expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null||:; }

Pokud chcete získat nenulový stavový kód na non-int, odstraňte ||: (neboli true ), ale ponechte ;

Testy

# 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
)

Testovací výstup

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

Poznámka

Byl jsem poslán do této králičí nory, protože přijatá odpověď není kompatibilní s set -o nounset (také znám jako 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

Linux
  1. Jak převést CentOS 8 na CentOS Stream

  2. Jak použít Sed k výměně víceřádkového řetězce?

  3. Jak rozdělit řetězec ve skriptu Bash

  1. Jak převést výstup shellu Linuxu do HTML?

  2. Jak hledat přesné slovo, pokud má řetězec v sobě tečku

  3. Jak používat atomové proměnné v C?

  1. Jak nahradit řetězec v souboru (souborech)?

  2. Jak mohu převést ukazatel na soubor ( FILE* fp ) na deskriptor souboru (int fd)?

  3. Jak převedu tar.bz2 na tar.gz?