2010-10-16 25 views
3

Je veux trouver la pluviométrie moyenne de trois états, disons CA, TX et AX pour un mois particulier de Jan à Dec. Donné le fichier d'entrée délimité par TAB SPACES et a le format city name, the state , and then average rainfall amounts from January through December, and then an annual average for all months. EG peut ressembler àProgramme AWK pour trouver la pluviométrie moyenne de trois états

AVOCA PA 30 2.10 2.15 2.55 2.97 3.65 3.98 3.79 3.32  3.31 2.79 3.06 2.51 36.18 
BAKERSFIELD CA 30 0.86 1.06 1.04 0.57 0.20 0.10 0.01 0.09 0.17 0.29 0.70 0.63 5.72 

Ce que je veux faire est « Pour obtenir la somme des précipitations moyennes pour dire un feb mois particulier, plus dire n années, puis trouver la moyenne pour les états CA, TX et AX.

J'ai écrit le script ci-dessous awk pour faire la même chose, mais ça ne me donne pas le résultat attendu

/^CA$/ {CA++; CA_SUM+= $5} # ^CA$ - Regular Expression to match the word CA only 
/^TX$/ {TX++; TX_SUM+= $5} # ^TX$ - Regular Expression to match the word TX only 
/^AX$/ {AX++; AX_SUM+= $5} # ^AX$ - Regular Expression to match the word AX only 
END { 
    CA_avg = CA_SUM/CA; 
    TX_avg = TX_SUM/TX; 
    AX_avg = AX_SUM/AX; 
    printf("CA Rainfall: %5.2f",CA_avg); 
    printf("CA Rainfall: %5.2f",TX_avg); 
    printf("CA Rainfall: %5.2f",AX_avg); 
    } 

J'invoque le programme avec la commande awk 'FS="\t"'-f awk1.awk rainfall.txt et ne voient pas la sortie.

Question: Où est-ce que je glisse? Toutes les suggestions et un code modifié seront appréciés

+0

Vous n'avez pas encore décrit avec précision vos données; le contenu de la colonne 3 ne semble pas être une quantité de pluie. Il n'est pas clair comment vous faites face à une ville avec deux mots dans son nom (Mountain View, Atlantic City). –

Répondre

2

votre regexp devrait être

/ CA/{CA++; cA_SUM+= $5} # ^CA$ - Regular Expression to match the word CA only 
/TX/{TX++; TX_SUM+= $5} # ^TX$ - Regular Expression to match the word TX only 
/AX/{AX++; AX_SUM+= $5} # ^AX$ - Regular Expression to match the word AX only 

/^ AX $/match que si elle est le seul mot dans la ligne

HTH!

EDIT

/ CA/{CA++; CA_SUM+= $5} # ^CA$ - Regular Expression to match the word CA only 
/TX/{TX++; TX_SUM+= $5} # ^TX$ - Regular Expression to match the word TX only 
/AX/{AX++; AX_SUM+= $5} # ^AX$ - Regular Expression to match the word AX only 
END { 

if(CA!=0){CA_avg = CA_SUM/CA;  printf("CA Rainfall: %5.2f",CA_avg);} 
if(TX!=0){TX_avg = TX_SUM/TX;  printf("TX Rainfall: %5.2f",TX_avg);} 
if(AX!=0){TX_avg = AX_SUM/CA;  printf("AX Rainfall: %5.2f",AX_avg);} 
} 
+0

@belisarius - ne fonctionne pas - Je ne vois pas de sortie à nouveau. –

+0

@Internative essayez de supprimer votre FS de la ligne de commande –

+0

@belisarius: Donne-moi une division par erreur zéro –

3

Le motif /^CA$/ signifie que le caractère "C" et "A" sont les seuls caractères sur la ligne. Vous voulez:

$2 == "CA" {CA++; CA_SUM+= $5} 
# etc. 

Cependant, ceci est Dryer:

{ count[$2]++; sum[$2] += $5 } 
END { 
    for (state in count) { 
     printf("%s Rainfall: %5.2f\n", state, sum[state]/count[state]) 
    } 
} 

En outre, cela semble erroné: awk 'FS="\t"'-f awk1.awk rainfall.txt
essayer: awk -F '\t' -f awk1.awk rainfall.txt


Réponse aux commentaires:

awk -F '\t' -v month=2 -v states="CA,AZ,TX" ' 
    BEGIN { 
     month_col = month + 3 # assume January is month 1 
     split(states, wanted_states, /,/) 
    } 
    { count[$2]++; sum[$2] += $month_col } 
    END { 
     for (state in wanted_states) { 
      if (state in count) { 
       printf("%s Rainfall: %5.2f\n", state, sum[state]/count[state]) 
      else 
       print state " Rainfall: no data" 
     } 
    } 
' rainfall.txt 
+1

+ 1 pour une solution plus générale et en mentionnant DRY dans le contexte de la pluie. – schot

+0

+1 Beaucoup mieux que le mien. Je pensais seulement à corriger les erreurs d'OP, qui engendre toujours une réponse à courte vue. Vous pouvez l'améliorer un peu plus en autorisant un paramètre dans la ligne de commande pour le numéro du mois. Juste mes 2 cents. –

+0

Vous pouvez changer votre version DRY pour sélectionner des états particuliers: 'awk -v statelist =" AK CA TX "'match (statelist, $ 2) {count [$ 2] ++; somme [$ 2] + = $ 5} ... '. Ou utilisez une variable shell à la place du littéral 'states =" AK CA TX "; awk -v statelist = $ états '... '' –