Incrémentation d'une variable à l'intérieur d'une boucle de Bash

j'essaie d'écrire un petit script qui comptera les entrées dans un fichier journal, et j'incrémente une variable (USCOUNTER) que j'essaie d'utiliser une fois la boucle terminée.

Mais à ce moment USCOUNTER semble être 0 au lieu de la valeur réelle. Toute idée de ce que je fais mal? Merci!

FILE=

tail -n10 mylog > $FILE

USCOUNTER=0

cat $FILE | while read line; do
  country=$(echo "$line" | cut -d' ' -f1)
  if [ "US" = "$country" ]; then
        USCOUNTER=`expr $USCOUNTER + 1`
        echo "US counter $USCOUNTER"
  fi
done
echo "final $USCOUNTER"

Il affiche:

US counter 1
US counter 2
US counter 3
..
final 0
28
demandé sur codeforester 2013-12-19 15:58:07

8 réponses

Vous utilisez USCOUNTER dans un sous-coquille, c'est pourquoi la variable n'apparaît pas dans la coquille principale.

au Lieu de cat FILE | while ..., est-ce juste un while ... done < $FILE. De cette façon, vous évitez le problème commun de la je mets des variables dans une boucle qui est dans un pipeline. Pourquoi disparaissent-ils après la boucle? Ou, pourquoi je ne peux pas Piper des données pour lire?:

while read country _; do
  if [ "US" = "$country" ]; then
        USCOUNTER=$(expr $USCOUNTER + 1)
        echo "US counter $USCOUNTER"
  fi
done < "$FILE"

Note j'ai aussi remplacé l'expression " par $().

j'ai aussi remplacé while read line; do country=$(echo "$line" | cut -d' ' -f1)while read country _. Ceci permet de dire while read var1 var2 ... varNvar1 contient le premier mot de la ligne, $var2 et ainsi de suite, jusqu'à ce que $varN contenant le reste du contenu.

37
répondu fedorqui 2016-07-25 11:21:31

minimaliste

counter=0
((counter++))
echo $counter
12
répondu geekzspot 2015-11-05 05:01:27

Vous obtenez final 0 parce que votre while loop est exécuté dans un processus sub (shell) et tout changement y apporté n'est pas reflété dans le shell actuel (parent).

Correct script:

while read -r country _; do
  if [ "US" = "$country" ]; then
        ((USCOUNTER++))
        echo "US counter $USCOUNTER"
  fi
done < "$FILE"
12
répondu anubhava 2016-09-02 11:36:42

j'ai eu la même variable $count dans une boucle de temps se perdre problème.

la réponse de@fedorqui (et quelques autres) sont des réponses précises à la question: le sous-shell est bien le problème.

mais ça m'a mené à un autre problème: Je ne pipais pas le contenu d'un fichier... mais la sortie d'une série de pipes et grep...

mon erroring exemple de code:

count=0
cat /etc/hosts | head | while read line; do
  ((count++))
  echo $count $line
done
echo $count

et mon corrigé grâce à l'aide de ce fil et le processus la substitution:

count=0
while IFS= read -r line; do
  ((count++))
  echo "$count $line"
done < <(cat /etc/hosts | head)
echo "$count"
6
répondu jobwat 2017-03-08 14:49:09
USCOUNTER=$(grep -c "^US " "$FILE")
2
répondu Walter A 2014-02-26 16:11:42

Incrémentation d'une variable qui peut être fait comme ça:

  _my_counter=$[$_my_counter + 1]

pour compter le nombre d'occurrence d'un motif dans une colonne peut être fait avec grep

 grep -cE "^([^ ]* ){2}US"

-c count

([^ ]* ) Pour détecter une colonne

{2} la colonne nombre

US votre profil

0
répondu trax 2016-11-02 11:03:58

en utilisant la commande suivante d'une ligne pour changer le nom de nombreux fichiers dans linux en utilisant la spécificité de phrase:

find -type f -name '*.jpg' | rename 's/holiday/honeymoon/'

Pour tous les fichiers avec l'extension ".jpg", s'ils contiennent la chaîne de caractères "holiday", remplacez-la par "honeymoon". Par exemple, cette commande renommerait le fichier "ourholiday001."jpg" à "ourhoneymoon001.jpg".

Cet exemple montre également comment utiliser la commande rechercher pour envoyer une liste de fichiers (type f) avec l'extension .jpg (- name'*.jpg') à renommer via une pipe ( / ). renommer lit ensuite sa liste de fichiers à partir de l'entrée standard.

0
répondu thanh 2017-01-04 12:22:12