bash script & array - ukázka řešení

Miroslav BENES miroslav.benes na zdas.cz
Úterý Leden 18 10:15:59 CET 2005


>A co tak usporiadat a vypisat vsetky cisla madzi dvoma prvkami
>usporiadanej mnoziny (suboru) ip adries.
>  
>
No sice jsem to zkoušel vyřešit tímto Vámi navrhovaným způsobem, ale 
napoprvé to nedopadlo úplně dobře (vstupní soubor je uspořádaný, což 
ulehčuje situaci) :

IP=0
cat $ARCHIV_MERGE |\
    sed -e 's/\./\ /g' |\
    awk '{printf("%d\n",$4)}' |\
    while read IP_ZIVA ;
        do
            for (( IP_MRTVA=$IP ; $IP_MRTVA < $IP_ZIVA  ; IP_MRTVA += 1 )) ;
                do
                    echo "volno : $ZAKLAD$PODSIT.$IP_MRTVA"
                done
            IP=$((IP_ZIVA + 1))
        done


Vypisuje to hezky, ale chyba se objeví na konci. Pokud jsou mezi 
"živými" IP adresami 247 a 250, vypíše se v posledním cyklu interval 
mezi nimi (248,249) - což je správně - ale už to nepokračuje dál a 
nevypíšou se další volné (251..255).

Zkusil jsem to doplnit o :
for (( IP_MRTVA=$IP_ZIVA + 1 ; $IP_MRTVA < 256  ; IP_MRTVA += 1 )) ;
    do
        echo "volno : $ZAKLAD$PODSIT.$IP_MRTVA"
    done

.. ale po skončení předchozího cyklu while nejsou proměnné naplněny. 
Tedy stejný problém jako poprvé jen s tím rozdílem, že takto už se 
vypíšou "skoro všechny" hledané hodnoty.


Protože se mi ale nechtělo bádat nad tím, jak z toho cyklu žijícího v 
podprocesu vydolovat hodnoty proměnných, napadly mě dvě úpravy :

a) jednodušší, ale napadlo mě později :
 - při výpisu se nevypisují volné IP adresy z "posledního volného 
úseku". Aby se také vypsal, musí se ohraničit - tedy přidat jednu 
fiktivní "živou" IP na konec :

IP=0
( cat $ARCHIV_MERGE ; echo $ZAKLAD$PODSIT.256 ) |\
    sed -e 's/\./\ /g' |\
...

b) složitější, ale také funkční
 - problém je v tom, že se na cyklus "while read" za rourou použije nový 
podproces, ze kterého se nedají jednoduše vracet hodnoty v proměnných. 
Ale celkem bez problémů je vracení hodnot :

declare -a IP_POLE

for (( IP=0 ; $IP < 256 ; IP += 1  )) ;
    do
        IP_POLE[$IP]=V
    done

for IP in `
                cat $ARCHIV_MERGE |\
                sed -e 's/\./\ /g' |\
                awk '{printf("%d ",$4)}' ` ;
    do
        IP_POLE[$IP]=O
    done

for (( IP=0 ; $IP < 256 ; IP += 1  )) ;
    do
        if [ ${IP_POLE[$IP]} == V ] ; then
            echo "volno : $ZAKLAD$PODSIT.$IP"
        fi
    done


Při tomto způsobu zpracování se hodnoty vytřídí a vrátí jako seznam 
pomocí vyhodnocení v obrácených apostrofech. Zbytek - tj. ukládání 
informace do pole - je tak jsem zamýšlel v době psaní prvního dotazu. 
Výhodou tohoto způsobu je to, že vstupní seznam "živých" IP adres nemusí 
být setříděný.


Děkuji všem zúčastněným za pomoc.






Další informace o konferenci Linux