2013-01-23 1 views
0

J'utilise awk pour calculer des sommes et je veux les stocker dans un fichier.obtenir le résultat de awk et l'imprimer dans un fichier

ici est mon fichier d'entrée:

misses 15 
hit 18 
misses 20 
hit 31 

Je veux imprimer les misses au total, et au total dans un succès fichier.

Si je lance ceci:

awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt 

je les vois dans le terminal.

Maintenant, je veux écrire le dans un fichier:

J'ai essayé ceci:

#!/bin/bash 
awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt 

echo misses $misses > $1; #first one overwrites the previous $1 is the argument given in the command line 
echo hits $hits>> $1; # all the othes append to the .txt file 

mais $misses, and $hits n'ont pas de valeur.

J'ai aussi essayé ceci:

#!/bin/bash 
result= $(echo $output | awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt) 
# $NF if I want the last column 
echo $result 

que j'ai vu sur le web, afin de voir ce que $ result me ​​retourner, mais je reçois cette erreur:

./test2.sh: line 2: Hits:: command not found 

Répondre

3

hits et misses ne sont que des variables à l'intérieur awk, pas dans la coquille après awk sorties. Il suffit de faire ce qui suit:

#!/bin/bash 
awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt > $1 

Dans votre deuxième tentative, vous ne pouvez pas mettre un espace après le '=':

result=$(echo $output | awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt) 
1

simplement rediriger la sortie de la commande awk:

awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt >file.txt 

l'opérateur redirection > peut être ajouté à tout sh commande ell pour rediriger sa sortie standard vers un fichier. le modifier à >> ajoute la sortie de la commande au fichier au lieu d'écraser complètement le fichier, comme vous l'avez remarqué.

modifier:

la raison pour laquelle cela ne fonctionne pas:

#!/bin/bash 
awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt 

echo misses $misses > $1; #first one overwrites the previous $1 is the argument given in the command line 
echo hits $hits>> $1; # all the othes append to the .txt file 

est parce que $ misses et $ hits sont des variables locales au script awk. ainsi, le shell n'a aucune connaissance d'eux en dehors de cette déclaration, alors quand vous essayez de leur faire écho, vous obtenez des blancs.

et cela ne fonctionne pas:

#!/bin/bash 
result= $(echo $output | awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt) 
# $NF if I want the last column 
echo $result 

pour de multiples raisons.

1) lors de l'attribution des variables dans bash, vous ne pouvez pas avoir des espaces autour du signe égal, donc la deuxième ligne doit commencer:

`result=$(echo...` 

2) l'instruction echo dans votre substitution (echo $output) est inutile. b) la deuxième instruction dans le pipeline (l'instruction awk) ignore complètement la sortie standard de la commande qui la précède dans le pipeline puisque vous lui avez spécifié un nom de fichier agir sur (t.txt).de sorte que la deuxième ligne pourrait être juste:

result=$(awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt) 

3) l'instruction echo à la fin affiche les résultats sur une seule ligne, en dépit du fait que les impressions de déclaration de awk deux lignes. C'est parce que vous n'avez pas cité la variable dans votre déclaration d'écho. essayez ceci:

echo "$result" 

en règle générale dans les scripts bash, vous devez toujours indiquer les variables que vous passez, ou l'impression, à moins que vous savez très bien pourquoi vous ne voulez pas.

espérons que vous en apprendre un peu plus sur ce que vous essayiez!

0

Voici une solution plus compacte:

#!/bin/bash 
awk ' 
    {tally[$1] += $2} 
    END { 
     for (outcome in tally) { 
      print outcome ":", tally[outcome] 
     } 
    }' t.xt > $1 

Vous ne pas avoir à initialiser les variables en AWK. La première fois que vous l'utiliserez, AWK supposera 0 pour le nombre, ou "" pour la chaîne, dépendra du contexte.

Questions connexes