Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 23/01/2012, à 14:20

compte supprimé

[Résolu] Bash soustraction en boucle

Bonjour la communauté smile

J'ai le fichier "fichier.txt" contenant ça comme donné :

0
80
300
600
1000
1500
2200

J'aimerais faire ceci, prendre la valeur de la 2ème ligne moins la valeur de la 1er ligne
valeur 3ème ligne - valeur 2ème ligne
valeur 4ème ligne - valeur 3ème ligne
...

Jusqu'à la fin du fichier.

J'ai trouver un début de réponse pour la première opération mais c'est là que je bloque car il faudrait crée une boucle... pour continué jusqu'au dernière ligne mais comment ??? hmm

echo "scale=2; $(cat fichier.txt | awk 'NR==2 {print $1}') - $(cat fichier.txt | awk 'NR==1 {print $1}')" | bc

Dernière modification par Orion79 (Le 04/03/2012, à 13:13)

#2 Le 23/01/2012, à 14:41

pingouinux

Re : [Résolu] Bash soustraction en boucle

Bonjour,
Ceci devrait convenir :

awk '{n[NR]=$0}END{for(i=1;i<NR;i++){printf("%d\n",n[i+1]-n[i])}}' fichier.txt

Autre suggestion, moins élégante :

dc <(paste <(tail -n +2 fichier.txt) <(head -n -1 fichier.txt) | sed 's/$/ -p/')

Encore une autre :

awk '{for(i=1;i<NF;i++){printf("%d\n",$(i+1)-$i)}}' <<<$(cat fichier.txt)

Dernière modification par pingouinux (Le 23/01/2012, à 14:59)

Hors ligne

#3 Le 23/01/2012, à 15:13

sputnick

Re : [Résolu] Bash soustraction en boucle

Ton titre est contradictoire avec ta description !

S'agit-il d'addition ou de soustraction ? oO


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#4 Le 23/01/2012, à 15:34

Watael

Re : [Résolu] Bash soustraction en boucle

salut,

tant qu'on reste dans les entiers, il n'y a aucune raison d'utiliser un programme externe.
le shell s'en débrouille très bien.

quelle doit-être la sortie du script?

Dernière modification par Watael (Le 23/01/2012, à 15:35)


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#5 Le 23/01/2012, à 15:41

credenhill

Re : [Résolu] Bash soustraction en boucle

hello

$ awk 'NR > 1{print $0-x} {x=$0}' fichier.txt
80
220
300
400
500
700
$ 

Hors ligne

#6 Le 23/01/2012, à 17:24

compte supprimé

Re : [Résolu] Bash soustraction en boucle

sputnick a écrit :

Ton titre est contradictoire avec ta description !

S'agit-il d'addition ou de soustraction ? oO

C'est corrigé ! Merci de la remarque...

Dernière modification par Orion79 (Le 23/01/2012, à 20:30)

#7 Le 23/01/2012, à 21:00

compte supprimé

Re : [Résolu] Bash soustraction en boucle

Merci à vous 2 pour vos solutions qui fonctionnent toutes ! smile

Cependant étant curieux par nature j'essaye de comprendre cette commande :

awk 'NR>1 {print $0-x} {x=$0}' fichier.txt

NR > 1  lignes 1 et suivante (jusqu'à la dernière)
{print $0-x} {x=$0} là je ne saisi pas tout ?

#8 Le 23/01/2012, à 21:11

sputnick

Re : [Résolu] Bash soustraction en boucle

{print $0-x} : afficher la ligne courante - la valeur de la variable x
{x=$0} : stocke la valeur de la ligne courante


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#9 Le 23/01/2012, à 21:18

sputnick

Re : [Résolu] Bash soustraction en boucle

Ou encore en pure bash :


$ cat /tmp/a
0
80
300
600
1000
1500
2200

$ while read a; do v=$((a - x)); ((v>0)) && echo $v; x=$a; done < /tmp/a
80
220
300
400
500
700

On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#10 Le 24/01/2012, à 09:39

credenhill

Re : [Résolu] Bash soustraction en boucle

Orion79 a écrit :

NR > 1  lignes 1 et suivante (jusqu'à la dernière)?

ligne 2 et  suivantes, NR commence à 1, pas à 0 comme les tableaux, donc le premier bloc {} n'est pas exécuté pour la ligne 1

edit : autre méthode pure bash

$ t=($(<fichier.tt));for x in $(seq 1 $((${#t[@]}-1))) ; do echo $((${t[$x]}-${t[$(($x-1))]})) ; done
80
220
300
400
500
700
$ 

Dernière modification par credenhill (Le 24/01/2012, à 12:21)

Hors ligne

#11 Le 24/01/2012, à 13:04

Watael

Re : [Résolu] Bash soustraction en boucle

désolé credenhill, `seq' n'est pas une commande bash.
pour être pur bash

for (( x=0; x<${#t[@]}; x++)); do echo $((${t[x]}-${t[x-1]})) ; done

Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#12 Le 24/01/2012, à 13:27

credenhill

Re : [Résolu] Bash soustraction en boucle

juste !!, mais il faut  for (( x=1; x<${#t[@]}; x++));.......
ou

$ t=($(<a3));for x in $(eval echo {1..$((${#t[@]}-1))}) ; do echo $((${t[x]}-${t[x-1]})) ; done
80
220
300
400
500
700
$ 

Dernière modification par credenhill (Le 24/01/2012, à 13:38)

Hors ligne

#13 Le 24/01/2012, à 14:14

Watael

Re : [Résolu] Bash soustraction en boucle

bien sûr x=1

mais avec `eval', c'est moche.


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#14 Le 24/01/2012, à 15:18

credenhill

Re : [Résolu] Bash soustraction en boucle

oui, oui, le for ( (...))  est  fait pour ça

Hors ligne

#15 Le 24/01/2012, à 17:21

sputnick

Re : [Résolu] Bash soustraction en boucle

Ceci est en pure bash, plus simple que vos dernières solutions, plus court et surtout plus lisible tongue


$ cat f
0
80
300
600
1000
1500
2200

$ c=0; while read a; do ((c++)); ((c==1)) && continue || echo $((a - x)); x=$a; done < f
80
220
300
400
500
700

On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#16 Le 24/01/2012, à 19:22

compte supprimé

Re : [Résolu] Bash soustraction en boucle

Awk c'est pas du "pur" bash ?

Pourtant de toute les solutions proposées cela est la plus simple...

awk 'NR>1 {print $0-x} {x=$0}' fichier.txt

#17 Le 24/01/2012, à 21:05

sputnick

Re : [Résolu] Bash soustraction en boucle

Non, awk c'est du pur awk ;p (awk c'est presque un langage de programmation, tout comme bash)

Mais cette solution est effectivement la plus courte et la plus pertinente, comme ça tu a le choix et ça peux intéresser les puristes de bash pour les autres solutions.


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#18 Le 24/01/2012, à 21:35

aduxas

Re : [Résolu] Bash soustraction en boucle

sputnick a écrit :

Mais cette solution est effectivement la plus courte et la plus pertinente, comme ça tu a le choix et ça peux intéresser les puristes de bash pour les autres solutions.

C'est le cas de le dire.  Sur un fichier de 61000 lignes, awk met 0.15 secondes.  Les puristes attendront 21 secondes.

Hors ligne

#19 Le 24/01/2012, à 21:48

sputnick

Re : [Résolu] Bash soustraction en boucle

Il est parfois plus pertinent de comprendre ce qu'on fait et utiliser bash que d'être rapide à tout prix (pour la maintenance par exemple) avec des technos obscures comme Awk, C, Perl. Ça dépends du contexte wink


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#20 Le 24/01/2012, à 22:15

Totor

Re : [Résolu] Bash soustraction en boucle

d'autres approches :

set -- $(<f)
for entier; do [[ $old ]] && echo $(( entier - old )); old=$entier;done

fi=( $(<f) )
for index in ${!fi[@]}; do ((index)) && echo $((fi[index] - fi[index-1])); done

edit : certaines syntaxes de bash sont également obscures ....

Dernière modification par Totor (Le 24/01/2012, à 22:15)


-- Lucid Lynx --

Hors ligne

#21 Le 24/01/2012, à 22:37

aduxas

Re : [Résolu] Bash soustraction en boucle

Totor a écrit :

edit : certaines syntaxes de bash sont également obscures ....

Je n'osais pas le dire smile

Hors ligne

#22 Le 24/01/2012, à 23:02

sputnick

Re : [Résolu] Bash soustraction en boucle

Ce que je voulait dire c'est que c'est plus facile en bash de faire qq chose de lisible.

Bien sur qu'on peux "obfuscate" du bash wink


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#23 Le 25/01/2012, à 09:57

credenhill

Re : [Résolu] Bash soustraction en boucle

variation sur le code de spoutnick au #15

$ c=0; while read a; do ((c++)) && echo $((a - x)); x=$a; done < fichier.txt
80
220
300
400
500
700
$ 

Dernière modification par credenhill (Le 25/01/2012, à 09:57)

Hors ligne

#24 Le 25/01/2012, à 12:58

compte supprimé

Re : [Résolu] Bash soustraction en boucle

credenhill a écrit :

variation sur le code de spoutnick au #15

$ c=0; while read a; do ((c++)) && echo $((a - x)); x=$a; done < fichier.txt
80
220
300
400
500
700
$ 

Ça ressemble beaucoup à cette commande :

awk 'NR>1 {print $0-x} {x=$0}' fichier.txt

Mais avec l'avantage d'être du "pur" bash, comme ça tout le monde sera content . smile

#25 Le 25/01/2012, à 23:33

sputnick

Re : [Résolu] Bash soustraction en boucle

Orion79, c'est que credenhill a réussit à optimiser ma ligne de commande de façon subtile wink

En fait, 0 dans un contexte arithmétique est faux (au sens de la logique booléenne)

Bravo credenhill, bien ouèj tongue


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne