Script bash auto_increment et colonnes

Résolu/Fermé
dave jnr Messages postés 36 Date d'inscription jeudi 4 février 2010 Statut Membre Dernière intervention 5 février 2014 - 20 nov. 2011 à 00:28
dave jnr Messages postés 36 Date d'inscription jeudi 4 février 2010 Statut Membre Dernière intervention 5 février 2014 - 21 nov. 2011 à 03:10
Bonjour,

Voici le code de mon script bash :

#!/bin/bash
accueil()
{
id=0
while [ 1 ]
do
echo " "
echo " INFOS PERSONNE "
echo " "
echo "Entrer votre nom :"
read n

echo "Entrer votre prenom :"
read p

echo "Entrer votre age :"
read a

echo "Entrer votre adresse :"
read ad
cat infos2 | (while read ligne
do
let $[ id= 'expr $id + 1' ]
done )
echo "Données insérées! Merci"

echo " $id : $n : $p : $a : $ad " >> infos2
done
}
accueil



Ce code accepte les infos fournies par l'utilisateur (sauf l'ID) et les enregistre dans un fichier infos2 qui est au format suivant :

ID : Nom : Prénom : Age : Adresse

Je voudrais que l'ID soit généré automatiquement à chaque fois qu'une nouvelle ligne est insérée. Mais à chaque fois j'ai 0 dns le champ ID.
Je voudrais aussi que la largeur des colonnes soit fixe pour une présentation plus ordonnée (les deux points (:) toujours alignés).

Je n'arrive pas à implémenter ces tâches. Pouvez vous m'aider SVP.

Merci d'avance.


2 réponses

salut,

t'as appris à coder du bash quand, ou dans un livre qui date de quelle année ? on ne code plus comme ça maintenant.

autant un pipe que les parenthèses créent des sous-shells en dehors desquelles $id n'existe pas.
il faudrait faire le echo à l'intérieur des parenthèses.

mais bash permet de faire autrement
while read ligne  
do  
let $[ id= 'expr $id + 1' ]  
done <infos2

et ça sort d'où
let $[ id= 'expr $id + 1' ]
soit tu utilises l'évaluation arithmétique (même à l'ancienne comme tu le fais ici), soit let, soit expr, mais pas les trois.

enfin, pourquoi ne pas utiliser wc pour obtenir le nombre de lignes d'info2, que tu assignerais à id ?
0
jisisv Messages postés 3645 Date d'inscription dimanche 18 mars 2001 Statut Modérateur Dernière intervention 15 janvier 2017 934
Modifié par jisisv le 21/11/2011 à 05:25
Quelques conseils suppléméntaires:
Tu remplaceras avantageusement lers lignes
echo "Entrer votre nom :"
read n

par
read -p " Votre nom ? " nom

voir help read
* utilise des noms de variable parlants; lorsque tu réaliseras un script complexe, il sera lisible et plus maintenable.

Pourquoi placer des espaces supplémentaires entre les champs? Un ":" suffit. Ce sera plus facile à manier avec cut (man 1 cut)

De plus on n'encode jamais un age mais un(e) date/année... de naissance.
Johan
0
dave jnr Messages postés 36 Date d'inscription jeudi 4 février 2010 Statut Membre Dernière intervention 5 février 2014
Modifié par dave jnr le 20/11/2011 à 23:31
Merci beaucoup pour vos réponses mais je ne suis pas très sûr d'avoir compris vos explications..Pouvez-vous reformuler SVP?? Merci

Au fait @qqchquicommenceparQ je suis débutant en bash! ^^
0
- un pipe |, tout comme les parenthèses crée un sous-shell, en dehors duquel les variables qui y sont définies n'ont pas de valeurs
( var=12 ) 
echo $var
cela n'affiche rien, car var est définie dans le sous-shell entre parenthèses.
alors que
( var=12; echo $var )
affiche bien 12, car l'affichage est demandé depuis le sous-shell, dans lequel la variable est définie et existe.

- let évalue des expressions arithmétiques
$[ ] évalue des expressions arithmétiques (maintenant on utilise $(( )) )
expr est un programme externe qui évalue entre autre des expressions arithmétiques

utiliser les trois en même temps n'a pas de sens, un seul est suffisant.

- j'ai fait un test rapide, duquel il ressort qu'une boucle while est plus rapide que wc.
si tu peux utiliser bash4, mapfile paraît encore plus rapide.
mapfile -t < fichier.txt
echo ${#MAPFILE[@]}


- jisisv te parle entre autre du format de ton fichier, tu devrais adopter le format CSV (comma separated values), qui utilise un caractère unique (une virgule, un point-virgule, une tabulation...) pour séparer les champs d'un fichier de données.

- demander la date de naissance plutôt que l'âge permet de facilement faire évoluer l'âge au court du temps, alors que le contraire n'est pas aussi fiable.
imaginons un programme qui te demande quand il te pose une question, au lieu de te demander la date d'aujourd'hui. il sera difficile (si possible) demain de dire depuis combien de jour il t'a interrogé, alors que si il te demande la date, il sera très facilement de calculer que cela fait 1,2,3..jours qu'il l'a fait.
0
dave jnr Messages postés 36 Date d'inscription jeudi 4 février 2010 Statut Membre Dernière intervention 5 février 2014
21 nov. 2011 à 03:10
Merci encore @qqchquicommenceparQ pour ces explications : ). Je vais essayer de réécrire tout mon code en les suivant. Au fait (tu as sans doute dû le remarquer mais) je dois préciser que j'utilise MinGW sous Windows pour tester mes codes (vu que mon pc Ubuntu est en panne) donc il y a des différences de syntaxes. Mais de toutes façons je te ferais savoir si j'ai encore un problème.
0