Programowanie w Shellu (index)


Programowanie w Shellu (7) - arytmetyka, parametry skryptu

ZADANIE 7.1

Zbadać działania na liczbach całkowitych w bash.


$ echo $((2+3))
5

$ echo $[2*3-10]
-4

$ A=12 ; B=3

$ echo $((A*B))               (nie trzeba $A i $B)
36

$ let "C=2*A+3*B"             (cudzysłowy dla jednoznaczności)

$ echo $C                     (C jest stałą tekstową, a nie całkowitą)
33

$ let "SUMA=A+B" "ILOCZYN=A*B"          (można wiecej działań w linii)

$ echo "Suma wynosi ${SUMA}, iloczyn wynosi ${ILOCZYN}."
Suma wynosi 15, iloczyn wynosi 36.

$ unset A B C SUMA ILOCZYN              (porządki)

$ help declare
$ declare -i LICZNIK=1        (deklaracja atrybutu "integer")
$ echo $LICZNIK
1
$ LICZNIK=LICZNIK+4           (nie trzeba "let")
$ echo $LICZNIK
5
$ declare +i LICZNIK          (odebranie atrybutu)

ZADANIE 7.2

Stworzyć plik dodaj.sh postaci:


#!/bin/bash
#
# dodaj.sh 
#
# Dodaje liczby naturalne $1 i $2.

# Sprawdzenie, czy podany jest pierwszy argument
if [ -z "$1" ] ; then
    echo "Syntax: $0 liczba1 [liczba2]" >& 2
    exit 1
fi

# Sprawdzenie, czy podany jest drugi argument
if [ -z "$2" ] ; then
    echo "$1 + $1 = $(($1+$1))"
else
    echo "$1 + $2 = $(($1+$2))"
fi
exit 0

Uruchomić skrypt poleceniem: ./dodaj.sh

ZADANIE 7.3

Stworzyć plik nwd.sh postaci:


#!/bin/bash
#
# nwd.sh 
#
# Podaje najwiekszy wspolny dzielnik liczb $1 i $2.
# Stosuje algorytm Euklidesa.

# Sprawdzenie, czy podany jest pierwszy argument
if [ -z "$1" ] ; then
    echo "Syntax: $0 liczba1 [liczba2]" >& 2
    exit 1
fi

# Sprawdzenie, czy podany jest drugi argument
if [ -z "$2" ] ; then
    echo "NWD( $1 , $1 ) = $1"
    exit 0
fi

# Gdy podane sa dwa argumenty
A=$1
B=$2
while [ $A -ne $B ]
do
    if [ $A -gt $B ] ; then
        let "A=A-B"
    else
        let "B=B-A"
    fi
done
echo "NWD( $1 , $2 ) = $A"
exit 0

Uruchomić skrypt poleceniem: ./nwd.sh

ZADANIE 7.4

Stworzyć plik suma1.sh postaci:


#!/bin/bash
#
# suma1.sh 
#
# Skrypt sumuje swoje argumenty (liczby calkowite).
# Dziala poprawnie nawet przy braku argumentow.

N=0
SUMA=0
while [ "$1" ]
do
    let "SUMA=SUMA+$1" "N=N+1"
# Przesuwamy numeracje do nastepnego argumentu
    shift
done
echo "Suma ${N} podanych liczb wynosi ${SUMA}."
exit 0

Uruchomić skrypt poleceniem: ./suma1.sh 2 3 5

ZADANIE 7.5

Stworzyć plik suma2.sh postaci:


#!/bin/bash
#
# suma2.sh
#
# Wczytanie danych ze stdin i obliczenie sumy.
# Skrypt korzysta z funkcji read czytajacej ze stdin.

echo "Podaj kilka liczb (koniec przez [Ctrl]+[d])."
N=0 ; SX=0
while read X
do
    let "SX=SX+X"  "N=N+1"
done
echo "Suma ${N} podanych liczb wynosi ${SX}."
exit 0

Uruchomić skrypt poleceniem: ./suma2.sh

Jeżeli plik suma2.dat zawiera kolumnę liczb całkowitych, można znaleźć ich sumę za pomocą jednego z poleceń:


$ ./suma2.sh < suma2.dat

$ cat suma2.dat | ./suma2.sh

ZADANIE 7.6

Stworzyć plik filtr.sh postaci:


#!/bin/bash
#
# filtr.sh 
#
# Proba stworzenia filtra.

# Sprawdzenie, czy podany jest pierwszy argument
if [ -z "$1" ] ; then
    echo "Syntax: $0 [plik_txt | -]" >& 2
    exit 1
fi

# Jezeli pierwszym argumentem jest "-", to czytaj ze stdin... 
if [ "$1" = "-" ] ; then
    while read LINE
    do
echo ${LINE} | tr "a-z" "[c*]" | tr "A-Z" "[C*]" | tr "0-9" "[X*]"
    done
# ...w przeciwnym razie przetwarzaj $1
else
    tr "a-z" "[c*]" < $1 | tr "A-Z" "[C*]" | tr "0-9" "[X*]"
fi
exit 0

Uruchomić skrypt poleceniem (plik podany jako argument skryptu): ./filtr.sh /etc/passwd

Uruchomić skrypt poleceniem (plik podany na stdin): ./filtr.sh < /etc/passwd -

PRZESUWANIE ARGUMENTÓW W SKRYPTACH

Przesuwanie argumentów w skryptach w lewo wykonujemy poleceniem shift (argument $0 się nie zmienia; $# się zmienia). Można zrobić przesunięcie o większą liczbę argumentów, np. shift 3 (przesunięcie o 3 w lewo). W shellu sh musimy użyć shift, aby dostać się do argumentów powyżej $9. Bash pozwala odwołać się od ${10} do ${99} (konieczne są nawiasy klamrowe).


while [ "$1" ]                (dopóki niepusty)
do
    process $1
    shift
done

POLECENIE let

Bash wszystko co zostało umieszczone wewnatrz konstrukcji $((...)) lub $[...] uważa za wyrażenie arytmetyczne. Operacja $((...)) jest równoważna poleceniu let "..." (podwójne nawiasy implikują cudzysłowy w let). Dlatego w konstrukcji $((...)) nie trzeba używać dolara $ przed nazwami zmiennych.

POLECENIE expr

Polecenie expr jest w sh jedynym sposobem wykonywania obliczeń liczbowych. Argumentami dla expr muszą być liczby. Wynik jest typu calkowitego (* / % + -) lub prawda/fausz (= != > >= < <=). Ważne są odstępy pomiędzy argumentami.


$ type expr
expr is /usr/bin/expr
$ info expr

$ expr 5 + 10       (dodawanie)
15

$ expr 34 - 5       (odejmowanie)
29

$ expr 25 / 10      (dzielenie całkowitoliczbowe; ODSTĘPY!)
2

$ expr 25 % 10      (reszta z dzielenia)
5

$ expr 3 \* 4       (mnożenie; trzeba zasłonić znak * przed shellem!)
12

Programowanie w Shellu (index)