La façon facile de le faire est d'utiliser une table de hachage, qui est directement pris en charge par bash 4.x et bien sûr se trouve dans awk et perl. Si vous n'avez pas de table de hachage, vous devez faire une boucle deux fois: une fois pour collecter les valeurs uniques de la deuxième colonne, une fois pour totaliser.
Il y a plusieurs façons de le faire. En voici une amusante qui n'utilise pas awk, sed ou perl. Les seuls utilitaires externes que j'ai utilisés ici sont cut, sort et uniq. Vous pouvez même remplacer cut
avec un peu plus d'effort. En fait les lignes 5-9 auraient pu être écrites plus facilement avec grep, (grep $kind stock.txt
) mais j'ai évité cela pour montrer la puissance de bash.
for kind in $(cut -d\; -f 2 stock.txt | sort | uniq) ; do
total=0
while read d ; do
total=$((total+d))
done < <(
while read line ; do
[[ $line =~ $kind ]] && echo $line
done < stock.txt | cut -d\; -f3
)
echo "Total amount for $kind: $total"
done
Nous perdons la commande stricte de votre sortie d'origine ici. Un exercice pour vous pourrait être de trouver un moyen de ne pas le faire.
Discussion: La première ligne décrit un sous-shell avec un pipeline simple utilisant cut
. Nous lisons le troisième champ du fichier stock.txt
, avec des champs délimités par ;
, écrit \;
ici, donc le shell ne l'interprète pas. Le résultat est une liste de valeurs séparées par un saut de ligne de stock.txt
.Ceci est canalisé à sort
, puis uniq
. Ceci effectue notre étape de "regroupement", puisque le pipeline affichera une liste alphabétique des éléments de la deuxième colonne mais ne listera chaque élément qu'une fois, peu importe le nombre de fois qu'il est apparu dans le fichier d'entrée.
Sur la première ligne se trouve également une boucle for
typique: Pour chaque élément résultant de la sous-coque, nous bouclons une fois, en stockant la valeur de l'article dans la variable kind
. C'est l'autre moitié de l'étape de regroupement, en s'assurant que chaque ligne de sortie "Total" se produit une fois.
Sur la deuxième ligne total
est initialisée à zéro afin qu'elle soit réinitialisée chaque fois qu'un nouveau groupe est démarré.
La troisième ligne commence la boucle 'totalisation', dans laquelle pour la kind
actuelle, nous trouvons la somme de ses occurrences. nous déclarons ici que nous allons lire la variable d
depuis stdin à chaque itération de la boucle.
Sur la quatrième ligne du montant total se produit en fait: L'utilisation shell arithmatic on ajoute la valeur d
à la valeur total
.
La ligne cinq termine la boucle while, puis décrit son entrée. Nous utilisons la redirection d'entrée shell via <
pour spécifier que l'entrée de la boucle, et donc la commande read
, provient d'un fichier. Nous utilisons ensuite process substitution pour spécifier que le fichier sera réellement le résultat d'une commande.
Sur la sixième ligne, la commande qui alimentera la boucle de lecture continue commence. Il est lui-même une autre boucle while-read, cette fois en lisant dans la variable line
. Sur la septième ligne, le test est effectué via un conditional construct. Ici, nous utilisons [[
pour son opérateur =~
, qui est un opérateur de correspondance de modèle. Nous testons pour voir si $line
correspond à notre $kind
actuel.
Sur la huitième ligne on finit la boucle while lecture interne et précisons que son entrée provient du fichier stock.txt
, puis on conduit la sortie de la boucle entière, ce qui en est maintenant simplement toutes les lignes correspondant à $kind
, à cut
et ordonnez-lui de n'afficher que le troisième champ, qui est le champ numérique. Sur la ligne 9, nous terminons alors la commande de substitution de processus, dont la sortie est une liste de nombres délimités par une nouvelle ligne à partir des lignes qui faisaient partie du groupe spécifié par kind
. Etant donné que le total est maintenant connu et que le type est connu, il est simple d'imprimer les résultats à l'écran.
Merci d'être honnête. Ouais, il est tentant d'obtenir la solution directe, mais vous serez foutu du temps d'examen si nous le faisons pour vous. Mais les gens ici sont heureux de vous donner quelques idées. –
Salut Rafe, c'est ce que je suis inquiet .. Examen .. hhaha .. Donc je dois être honnête, et trouver la solution par moi-même, mais j'ai besoin de vos directives, les notes de cours que j'ai sont très limitées, manque d'exemples . – bashington02
Existe-t-il des restrictions sur les outils que vous êtes autorisé à utiliser? awk pourrait le faire assez facilement ... –