Calcul sur des colonnes dans le shell
Résolu
sheol
-
jipicy Messages postés 41342 Statut Modérateur -
jipicy Messages postés 41342 Statut Modérateur -
Bonjour,
J'ai un soucis !
Cela fait plusieurs jours (... Je sais je suis nul) que j'essaye de faire la chose suivante :
J'ai un fichier qui se présente comme cela :
1 5.178
2 5.178
3 2.982
4 2.982
5 2.882
6 2.881
7 2.881
8 2.882
1 3.016
2 3.016
3 2.993
4 2.993
5 3.033
6 3.034
7 3.034
8 3.034
Sachant que 8 est en fait une variable (ça peut etre un autre nombre, c'est pris dans un fichier).
Ce dont j'ai besoin, c'est de manipuler ces fichiers de telle sorte qu'en sortie j'ai :
1 2.162 # soit `5.178-3.016`
2 2.162
3 -.011 # soit 2.982-2.993
4 xxx
5 xxx
6 xxx
7 xxx
8 xxx
Pour chaque valeur de i allant de 1 à $NombredAtomes (ici $NombredAtomes=8 ), j'ai besoin qu'il m'affiche la différence entre la première et la deuxième apparition du nombre à coté de i.
J'espère que c'est assez clair ...
C'est en fait des valeurs de spin électronique pour des boites de $NombredAtomes atomes. Et j'ai besoin qu'il me fasse spinup - spindown pour chacun de ces atomes.
Voilivoila !
Déjà merci de m'avoir lu jusqu'ici :), même si vous n'avez pas la réponse.
J'ai un soucis !
Cela fait plusieurs jours (... Je sais je suis nul) que j'essaye de faire la chose suivante :
J'ai un fichier qui se présente comme cela :
1 5.178
2 5.178
3 2.982
4 2.982
5 2.882
6 2.881
7 2.881
8 2.882
1 3.016
2 3.016
3 2.993
4 2.993
5 3.033
6 3.034
7 3.034
8 3.034
Sachant que 8 est en fait une variable (ça peut etre un autre nombre, c'est pris dans un fichier).
Ce dont j'ai besoin, c'est de manipuler ces fichiers de telle sorte qu'en sortie j'ai :
1 2.162 # soit `5.178-3.016`
2 2.162
3 -.011 # soit 2.982-2.993
4 xxx
5 xxx
6 xxx
7 xxx
8 xxx
Pour chaque valeur de i allant de 1 à $NombredAtomes (ici $NombredAtomes=8 ), j'ai besoin qu'il m'affiche la différence entre la première et la deuxième apparition du nombre à coté de i.
J'espère que c'est assez clair ...
C'est en fait des valeurs de spin électronique pour des boites de $NombredAtomes atomes. Et j'ai besoin qu'il me fasse spinup - spindown pour chacun de ces atomes.
Voilivoila !
Déjà merci de m'avoir lu jusqu'ici :), même si vous n'avez pas la réponse.
A voir également:
- Calcul sur des colonnes dans le shell
- Comment faire des colonnes sur word - Guide
- Classic shell - Télécharger - Personnalisation
- Formule moyenne excel plusieurs colonnes - Guide
- Classer par ordre alphabétique excel plusieurs colonnes - Guide
- Dans le fichier, générez ce tableau automatiquement (tableau croisé dynamique ou table de pilote) à partir des quatre premières colonnes. - Guide
8 réponses
Salut,
[tmpfs]$ cat fich.txt
1 5.178
2 5.178
3 2.982
4 2.982
5 2.882
6 2.881
7 2.881
8 2.882
1 3.016
2 3.016
3 2.993
4 2.993
5 3.033
6 3.034
7 3.034
8 3.034
[tmpfs]$ cat foo.sh
#! /bin/bash
#set -x
nbre=$1
nbre2=$((nbre+1))
A=( $(sed -ne "1,$nbre s/.[^ ]*//p" fich.txt | sed ':b;N;$! bb;s/\n/ /g') )
B=( $(sed -ne "$nbre2,$ s/.[^ ]*//p" fich.txt | sed ':b;N;$! bb;s/\n/ /g') )
i=0
while [ "$i" -le "$((nbre-1))" ]
do
echo -e "$((i+1)) \c" && echo "${A[$i]} - ${B[$i]}" | bc
i=$((i+1))
done
[tmpfs]$ ./foo.sh 8
1 2.162
2 2.162
3 -.011
4 -.011
5 -.151
6 -.153
7 -.153
8 -.152
[tmpfs]$:-))
hello
avec awk:
awk '{if (x[$1] == 0) x[$1]=$2 else printf("%d %6.3f\n", $1, x[$1] - $2)}' < fichier.txt
avec awk:
awk '{if (x[$1] == 0) x[$1]=$2 else printf("%d %6.3f\n", $1, x[$1] - $2)}' < fichier.txt
merci !!!!
jipicy, ta méthode marche super bien !
Par contre dubcek je ne sais pas pourquoi ça ne marche pas chez moi. Je n'ai pas les connaissances en awk suffisantes pour corriger ce qui doit etre une simple erreur de synthaxe surement, mais il me marque qu'il y a une "synthax error" au niveau du "else" dans ton script awk.
En tous cas merci bien à tous les deux.
dubcek si tu vois ta faute je veux bien que tu nous en fasses part s'il te plait comme ça j'apprendrais des choses en awk ! :)
+++
jipicy, ta méthode marche super bien !
Par contre dubcek je ne sais pas pourquoi ça ne marche pas chez moi. Je n'ai pas les connaissances en awk suffisantes pour corriger ce qui doit etre une simple erreur de synthaxe surement, mais il me marque qu'il y a une "synthax error" au niveau du "else" dans ton script awk.
En tous cas merci bien à tous les deux.
dubcek si tu vois ta faute je veux bien que tu nous en fasses part s'il te plait comme ça j'apprendrais des choses en awk ! :)
+++
En ce qui concerne l'erreur du "else" je l'ai noté dans l'édition de mon précédent message, il suffit de rajouter un point virgule avant le "else" :
awk '{if (x[$1] == 0) x[$1]=$2 ; else printf("%d %6.3f\n", $1, x[$1] - $2)}' < fichier.txtPar contre le résultat n'est pas celui attendu ;-(( :1 2,000 2 2,000 3 0,000 4 0,000 5 -1,000 6 -1,000 7 -1,000 8 -1,000???
pardon! je répondais au message à partir du mail envoyé par le site ... à l'époque de ton premier post.
Je n'avais donc pas connaissance de ton edit.
En tous cas le résultat est bizarre ! c'est comme s'il travaillait sur des entiers uniquement.
NB: je me suis inscrit :) :P
Je n'avais donc pas connaissance de ton edit.
En tous cas le résultat est bizarre ! c'est comme s'il travaillait sur des entiers uniquement.
NB: je me suis inscrit :) :P
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
effectivement, il manque un ; quand tout est sur la même ligne ,mais j'ai bien les décimales, mais j'utilise gawk.
C:\>gawk '{if (x[$1] == 0) x[$1]=$2 ; else printf("%d %6.3f\n", $1, x[$1] - $2)}' < g1.txt
1 2.162
2 2.162
3 -0.011
4 -0.011
5 -0.151
6 -0.153
7 -0.153
8 -0.152
ca serait pas un problème de . ou de , comme séparateur décimal ?
C:\>gawk '{if (x[$1] == 0) x[$1]=$2 ; else printf("%d %6.3f\n", $1, x[$1] - $2)}' < g1.txt
1 2.162
2 2.162
3 -0.011
4 -0.011
5 -0.151
6 -0.153
7 -0.153
8 -0.152
ca serait pas un problème de . ou de , comme séparateur décimal ?
ça marche parfaitement avec chez moi.
Pourquoi foo.sh ne fonctionne plus quand je l'intègre dans mon script ça me marque une erreur à la ligne :
B=( $(sed -ne "$nbre2,$ s/.[^ ]*//p" SpinUpDownList.tmp | sed ':b;N;$! bb;s/\n/ /g') )
mon script entier :
Pourquoi foo.sh ne fonctionne plus quand je l'intègre dans mon script ça me marque une erreur à la ligne :
B=( $(sed -ne "$nbre2,$ s/.[^ ]*//p" SpinUpDownList.tmp | sed ':b;N;$! bb;s/\n/ /g') )
mon script entier :
#/usr/bin/bash
echo "Which file ?"
read file
NumberOfAtoms=`grep NumberOfAtoms ${file} |sed s/NumberOfAtoms//g`
NumberOfSpecies=`grep NumberOfSpecies ${file}|sed s/NumberOfSpecies//g`
rm FullUpDownList.tmp
NumberOfLinesToGrep=$((1+10*${NumberOfSpecies}+4+4*${NumberOfAtoms}+5))
egrep -B${NumberOfLinesToGrep} Relaxed ${file} | egrep -v "[yz]2|orb|MB|scaled|Qtot|Cr|Fe" | sed /^$/d | sed /^...........................$/d | cut -d ' ' -f -6 | cut -d ' ' -f 4- | sed /^$/d > FullUpDownList.tmp
nbre=$NumberOfAtoms
nbre2=$((NumberOfAtoms+1))
A=( $(sed -ne "1,$nbre s/.[^ ]*//p" FullUpDownList.tmp | sed ':b;N;$! bb;s/\n/ /g') )
B=( $(sed -ne "$nbre2,$ s/.[^ ]*//p" FullUpDownList.tmp | sed ':b;N;$! bb;s/\n/ /g') )
i=0
while [ "$i" -le "$((nbre-1))" ]
do
echo -e "$((i+1)) \c" && echo "${A[$i]} - ${B[$i]}" | bc >>
i=$((i+1))
done
Ben là c'est difficile à dire ;-\
Exécute ton script en mode débogage (set -x) peut être que l'erreur sera plus parlante...
Sinon le fichier en entrée (FullUpDownList.tmp) est-il vraiment comparable à l'exemple fourni dans ton 1er post ?
Exécute ton script en mode débogage (set -x) peut être que l'erreur sera plus parlante...
Sinon le fichier en entrée (FullUpDownList.tmp) est-il vraiment comparable à l'exemple fourni dans ton 1er post ?
Re-bonjour !
En effet mon fichier FullUpDownList.tmp est exactement le même que l'exemple fourni dans mon premier post.
J'ai décidé, pour faire plus simple, d'apprendre le Perl. Ca fait une demi journée que je m'y suis mis et déjà je fais des choses que j'avais beaucoup de mal à faire en BASH scripts donc je suis vraiment content.
J'ai d'ailleurs déjà un petit soucis mais je vais ouvrir un nouveau topic. Merci à tous pour vos réponses !!!
C'est vraiment très cool.
+++++++++++++ sur d'autres topics ! :)
En effet mon fichier FullUpDownList.tmp est exactement le même que l'exemple fourni dans mon premier post.
J'ai décidé, pour faire plus simple, d'apprendre le Perl. Ca fait une demi journée que je m'y suis mis et déjà je fais des choses que j'avais beaucoup de mal à faire en BASH scripts donc je suis vraiment content.
J'ai d'ailleurs déjà un petit soucis mais je vais ouvrir un nouveau topic. Merci à tous pour vos réponses !!!
C'est vraiment très cool.
+++++++++++++ sur d'autres topics ! :)