GUIDA AD AWK, 12 – scripts interessanti

Scripts “interessanti”

 

ORDINAMENTO DECRESCENTE DI UNA SERIE NUMERICA

Le funzioni “asort” e “asorti” di gawk permettono l’ordinamento dei valori di un array.
Tali funzioni, però, non sono disponibili in awk e, se si vuole ordinare una serie numerica, occorre eseguire una successione di istruzioni piuttosto articolata. Di seguito la “mia” soluzione. Conoscete soluzioni migliori? Fatemelo sapere!

1. popolare due array contenenti la serie numerica che si intende ordinare
2. impostare una variabile con il numero di elementi della serie numerica
3. Iniziare 3 cicli nidificati di loop con for: nei loop interno ed intermedio confrontiamo ogni valore del primo array con ogni valore del secondo e impostiamo la variabile “max” col valore più alto per poi concatenarla alla variabile “sorted”. Prima di uscire dal loop intermedio cancello l’elemento del primo array corrispondente al valore più alto trovato. In tal modo ottengo che nel loop esterno ad ogni ricorsione l’array risulterà mancante dell’ultimo elemento cancellato.
4. Alla fine dei loop stampare la variabile “sorted”.

Ecco lo script prima nella forma finale e poi nella forma che produce un output verboso, per chi volesse visualizzare i vari passaggi:

---------------------------------------
#!/bin/bash

## se lanciato senza argomento, avviso ed esco
if [ "$1" = "" ]; then
echo "Inserire una serie numerica con valori separati da virgola";
exit;
fi
echo "$1" |
## Creo gli array arr1 e arr2 con lo split delle serie in input:
awk '{split($0,arr1,",");split($0,arr2,",");}
## imposto la var c con il count degli elementi
{c=split($0,arr1,",");}
## inizio i cicli di confronto fra i valori
{
for (k=c;k>=1;k--) {
## all inizio di ogni ciclo svuoto le variabili con
## il valore massimo precedente
max=""; d="";
for (i=c;i>=1;i--) {
for (n=c;n>=1;n--) {
## imposto max con valore massimo
if (arr1[i]>=arr2[n]) {
if (max<arr1[i]) {
max=arr1[i]; d=i
}
}
}
}
## accodo max a sorted
sorted=sorted max",";
## cancello dall array l elemento con valore massimo
delete arr1[d];
}
## stampo la serie ordinata
print "Serie ordinata: " sorted;
}'
---------------------------------

Stesso script con output verboso:

#!/bin/bash

## se lanciato senza argomento, avviso ed esco
if [ "$1" = "" ]; then
echo "Inserire una serie numerica con valori separati da virgola";
exit;
fi
echo "$1" |
## Creo gli array arr1 e arr2 con lo split delle serie in input:
awk '{split($0,arr1,",");split($0,arr2,","); \
## e stampo e due array
print " Array arr1 in input: "; for (a in arr1) print "["a"]" " = " arr1[a];print \
" Array arr2 in input: "; for (b in arr2) print "["b"]" " = " arr2[b];}
## imposto la var c con il count degli elementi
{c=split($0,arr1,",");print "numero elementi: " c;}
## inizio i cicli di confronto fra i valori
{

for (k=c;k>=1;k--) {
## all inizio di ogni ciclo svuoto le variabili con
## il valore massimo precedente
max=""; d="";
for (i=c;i>=1;i--) {
for (n=c;n>=1;n--) {
## stampo i numeri che confronto
printf " "arr1[i] " <<<<----->>>> " arr2[n]" " "\n"
if (arr1[i]>=arr2[n]) {
if (max<arr1[i]) {
max=arr1[i]; d=i
}
}

}

}
## stampo numero di loop e relativo valore massimo max
print "valore maggiore nel loop " ++l " : "max;
## accodo max a sorted
sorted=sorted max","; print sorted;
## cancello dall array l elemento con valore massimo
print " proseguo cancellando il valore trovato ";
delete arr1[d]; print " cancello ""arr1["d"]";
## stampo l array dopo cancellazione
print "nuovo array: ";
for (a in arr1) print "["a"]" " = " arr1[a];
}
## stampo la serie ordinata - fine
print " SERIE ORDINATA: " sorted;

}'
-------------------------------------

Se vogliamo rendere lo script più interattivo, possiamo sostituire le prime righe con queste:

#!/bin/bash

echo "Prego inserire serie numerica con separatore virgola, seguita da [ENTER]:"
read serie
echo "$serie" |

## Creo gli array arr1 e arr2 con lo split delle serie in input:
awk '{split($0,arr1,",");split($0,arr2,",");}
(...)

————————————

INDICE

Lascia una risposta

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *

È possibile utilizzare questi tag ed attributi XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>