2008-11-29 8 views
-1

Mon script bash ne fonctionne pas comme je le souhaite:Comment puis-je faire fonctionner mon script bash?

#!/bin/bash 

total="0" 
count="0" 
#FILE="$1" This is the easier way 
for FILE in $* 
do 
    # Start processing all processable files 
    while read line 
    do 
     if [[ "$line" =~ ^Total ]]; 
     then 
      tmp=$(echo $line | cut -d':' -f2) 
      count=$(expr $count + 1) 
      total=$(expr $total + $tmp) 
     fi  
    done < $FILE 
done 
echo "The Total Is: $total" 
echo "$FILE" 

Y at-il une autre façon de modifier ce script afin qu'il lit des arguments en $1 au lieu de $FILE? Je l'ai essayé d'utiliser une boucle while:

while [ $1 != "" ] 
    do .... 
done 

Aussi, quand je mets en œuvre que le code se répète. Y a-t-il un moyen de régler cela aussi?

Un autre problème que j'ai est que quand j'ai plusieurs fichiers hi*.txt il me donne des doublons. Pourquoi? J'ai des fichiers comme hi1.txthi1.txt~ mais le fichier tilde est de 0 octets, donc mon script ne devrait rien trouver.


Ce que j'ai est bien, mais pourrait être amélioré. J'apprécie vos suggestions awk mais c'est actuellement au-delà de mon niveau en tant que programmeur Unix. Strager: Les fichiers que mon éditeur de texte génère automatiquement ne contiennent rien .. il est de 0 octets..Mais ouais je suis allé de l'avant et les supprimés juste pour être sûr. Mais non, mon script est en train de tout lire deux fois. Je suppose que son looping encore quand il ne devrait pas. J'ai essayé de faire taire cette action avec les commandes de sortie ... Mais ce n'était pas réussi.

while [ "$1" != "" ]; do 
    # Code here 

    # Next argument 
    shift 
done 

Ce code est assez mignon, mais je spécifie toutes les commandes possibles en même temps. Exemple: hi [145] .txt Si fourni, les trois fichiers seraient lus simultanément. Supposons que l'utilisateur entre hi * .txt; Ensuite, je lis tous mes fichiers hi deux fois puis je les ajoute à nouveau.

Comment puis-je le coder pour qu'il lise mes fichiers (juste une fois) lors de la spécification de hi * .txt? Je pense vraiment que c'est parce que je n'ai pas 1 $.

+0

Veuillez formater votre code un peu mieux. Sélectionnez tout cela et cliquez sur le petit bouton de code, ou au moins assurez-vous qu'il est indenté de quatre espaces. – Dustin

Répondre

1

Si vous définissez une fonction, elle recevra l'argument $ 1. Pourquoi vaut-il 1 $ de plus que le FICHIER $?

#!/bin/sh 

process() { 
    echo "doing something with $1" 
} 

for i in "[email protected]" # Note use of "[email protected]" to not break on filenames with whitespace 
do 
    process "$i" 
done 
1
while [ "$1" != "" ]; do 
    # Code here 

    # Next argument 
    shift 
done 

Sur votre problème avec les fichiers tilde ... ce sont les fichiers temporaires créés par votre éditeur de texte. Supprimez-les si vous ne voulez pas qu'ils correspondent à votre expression globale (caractère générique). Sinon, filtrez-les dans votre script (non recommandé).

2

Il semble que vous essayez d'additionner les totaux des lignes intitulées «Total:» dans les fichiers fournis. C'est toujours une bonne idée d'indiquer ce que vous essayez de faire - ainsi que la façon dont vous essayez de le faire (voir How to Ask Questions the Smart Way).

Si oui, alors vous faites d'une manière aussi compliquée que je peux le voir. Quel était le problème avec:

grep '^Total:' "[email protected]" | 
cut -d: -f2 | 
awk '{sum += $1} 
    END { print sum }' 

Cela n'affiche pas "Le total est" etc; et il n'est pas clair pourquoi vous écrivez $ FILE à la fin de votre version.

Vous pouvez utiliser Perl ou tout autre programme approprié à la place de awk; vous pouvez faire tout le travail en Perl ou Python - en effet, le cut travail pourrait être fait par awk:

grep "^Total:" "[email protected]" | 
awk -F: '{sum += $2} 
     END { print sum }' 

Pris encore, tout le travail pourrait être fait par awk:

awk -F: '$1 ~ /^Total/ { sum += $2 } 
     END { print sum }' "[email protected]" 

Le code Perl ne serait pas beaucoup plus difficile et le résultat pourrait être plus rapide:

perl -na -F: -e '$sum += $F[1] if m/^Total:/; END { print $sum; }' "[email protected]" 

Lorsque itérer sur les arguments de nom de fichier fourni dans un script shell, vous devez utiliser '"[email protected]"' à la place de '$*' car la dernière notation ne conserve pas d'espaces dans les noms de fichiers.

Votre commentaire à propos de '$1' est confus pour moi. Vous pourriez demander à lire à partir du fichier dont le nom est $1 à chaque itération; cela est fait en utilisant:

while [ $# -gt 0 ] 
do 
    ...process $1... 
    shift 
done 

HTH!

Questions connexes