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 28/01/2022, à 13:27

Frankkunst

[RESOLU]traitement "chaîne de caratères"

Bonjour à tous,
Je devais extraire des données de fichier .txt ?
Étant autodidacte en informatique, je me suis lancé un défi et voici mon script :

#!/bin/bash
#-------------------Recherche et extraction de données des fichier.txt www.data.gouv.fr décès entre 1970 et 2021----------------------
#------------------------------------- Auteur Frankkunst / Date 26 janvier 2022 ----------------------------------------------------
E_ABANDON=100
E_MAUVAISARGS=65
E_SANSFICHIER=66
mondoss=/home/$USER/TEMPNECRO
mkdir $mondoss
(																	# texte de présentation et info
echo  "			*** NECRODC ***		auteur : Frankkunst		01.2022"
echo  " "
echo  "		Script de recherche des personnes décédées en France entre 1970 et 2021"
echo  " "
echo  "Étant prévu pour traiter exclusivement les fichiers .txt fournis sur www.data.gouv.fr, la présence des fichiers :"
echo  " "
echo  "			deces-AAAA.txt	(52 fichiers 1970 à 2021)"
echo  " "
echo  "			commune2021.csv"
echo  " "
echo  "			pays2021.csv"
echo  " "
echo  "		est indispensable à son fonctionnement"
echo  " "
echo  "Selon votre connection internet leurs téléchargement peut s'avérer long ... 5,3 Go"
echo  " "
echo  "Pour continuer appuyer sur \"Valider\"    Pour abandonner sur \"Annuler\""
)>>$mondoss/tempInfo.txt
declare -a tablan=( 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 )
declare -a tabldecis=( "continuer-la-recherche" "arrêter-le-programme" )

					#--------------------------------* Présentation *-------------------------------------------------------------
zenity --title=INFORMATION --text-info --width="650" --height="450" --filename "$mondoss/tempInfo.txt" 2>/dev/null
if [ $? -eq 1 ]
then
	rm $mondoss/tempInfo.txt
	rmdir $mondoss 
	exit $E_ABANDON
fi
clear
					#--------------------------------* entrée arguments et contrôle *----------------------------------------------
dossier=`zenity --file-selection --directory --title="Veuillez choisir le dossier de recherche" 2>/dev/null`
function fcontroldoss { ls -l "$dossier" | grep -q "deces-[[:digit:]][[:digit:]][[:digit:]][[:digit:]].txt" ; echo $?;}
if [ $(fcontroldoss) -ne 0 ]														# contole dossier
	then echo -e "\v\v\v\t\tLe dossier \"$dossier\" ne contient pas de fichier INSEE compatible, appuyer sur ENTRER "
		read ; rm $mondoss/tempInfo.txt ; rmdir $mondoss ; clear
		$0 ; exit $E_SANSFICHIER
fi
annee=`zenity  --list --text="Veuillez selectionner l'année" --column="ANNEE" ${tablan[*]} 2>/dev/null`
nomprenom=`zenity --entry --text="NOM	PRENOM	 à rechercher" --width="450" --height="140" 2>/dev/null`
set $nomprenom
nom=$1
prenom=$2
shopt -s extglob
case "$nom" in	      															# controle format du "NOM"
	+([[:upper:]]) )  echo -e "\v\tVous recherchez une personne dénomée : "$nom ;; 			# controle que le nom soit en majuscule
	* ) clear ; echo -e "\v\v\v\v\v\tVous devez entrer un nom en \e[0;31;01m\"MAJUSCULE\"\e[30;00m uniquement, si c'est un nom composé entrez seulement la première partie\v\v\v\t\t\t"
	read -p "	Appuyer sur ENTRER pour recommencer" ; rm $mondoss/tempInfo.txt ; rmdir $mondoss ; clear
	$0 ; exit $E_MAUVAISARGS
esac
if [ ${#prenom} -ne 0 ]
	then
	case "$prenom" in	      													# controle format du "PRENOM"
		+([[:upper:]]) ) echo -e "\v\tVous recherchez une personne prénomée : "$prenom ;; 	# controle prénom soit en majuscule
		* ) echo -e "\v\v\v\v\v\tVous devez entrer un prénom en \e[0;31;01m\"MAJUSCULE\"\e[30;00m uniquement la première partie \v\v\v\t\t\t"
		read -p "	Appuyer sur ENTRER pour recommencer" ; rm $mondoss/tempInfo.txt ; rmdir $mondoss ; clear
		$0 ; exit $E_MAUVAISARGS
	esac
fi
					#------------------------------------* positionnement dans le dossier *----------------------------------------
cd "$dossier"
echo -n -e "\v\v\tDans : $PWD\tsur l'année $annee\r\v\v"
					#----------------------------* début du travail de recherche dans les fichiers *-------------------------------
suff=.txt
for i in $(ls *"$annee"$suff)
do
					#---------------------------------------* découpage donnée *---------------------------------------------------
cat $i | grep -a "^$nom" | grep -w "$prenom" | cut -b 1-80,81,82-89,90-94,95-124,125-154,155-162,163-167,168-176 > $mondoss/tempDC
		#  garde les lignes commençant par le "NOM" demandé et "PRENOM" si précisé
					#----------------------------------------* tri argument *------------------------------------------------------
n=0																	# amorçage compteur de lignes trouvées
	while read ligne
	do
	n=$[ $n+1 ]
		echo $n
		echo -n -e "\rNom : "${ligne%%"*"*}; ligneX=${ligne##*"*"}; echo -n -e " Prenom : "${ligneX%%"/"*}
		sexe=${ligne:80:1}
		if [[ $sexe -eq 1 ]]												# controle le sexe et le nomme
			then
				echo -n -e "\tgenre : \033[;;46mHomme\033[0m"
			else
				echo -n -e "\tgenre : \033[;;42mFemme\033[0m"
		fi
		echo -n -e "\tDate de naissance : "${ligne:87:2}"/"${ligne:85:2}"/"${ligne:81:4}"\tLieu : "${ligne:89:5}
		com=${ligne:94:30} ; commune=${com%%  *}
		echo -e "\tCommune : $commune"
		pay=${ligne:124:30} ; pay1=${pay%% *}
		if [[ ${#pay1} -eq 0 ]]												# teste si la donnée "Pays" est vide
			then 
				echo -n "Pays : FRANCE"
			else
				echo -n "Pays : $pay"
		fi
		echo -n -e "\nDate de décès : "${ligne:160:2}"/"${ligne:158:2}"/"${ligne:154:4}"\tLieu : "${ligne:162:5}
		codecom=${ligne:162:5}
		cat $PWD/commune2021.csv | grep $codecom > /dev/null
		codesortx=$?
		if [[ $codesortx -eq 0 ]]
			then
				sortiecode=`cat $PWD/commune2021.csv | grep $codecom`
				retcom=(*,*,*,*,*,*,*,)
				communedc=${sortiecode#$retcom}
				echo -e "\tCommune de décès : "${communedc%%,*}
			else
				sortiecodepays=`cat $PWD/pays2021.csv | grep $codecom`
				retpays=(*,*,*,*,*,)
				paysdc=${sortiecodepays#$retpays}
			echo -e "\tPays de décès : "${paysdc%%,*}
		fi
		act=${ligne:167:9} ; acte=${act%% *}
		echo -e "\tacte de décès n° $acte\r\v\v"
	done < $mondoss/tempDC
	echo $n &>>$mondoss/compte-resultat2
done
rm $mondoss/tempDC
declare -i z=0
for i in $(cat $mondoss/compte-resultat2); do (( z = $z + $i )) ; done
echo -e "\v\v\tIl y a $z résultat(s)\v\t"
rm $mondoss/compte-resultat2
rm $mondoss/tempInfo.txt
rmdir /home/$USER/TEMPNECRO
decision=`zenity --list  --text="Que voulez-vous faire ?" --column="décision" ${tabldecis[*]} 2>/dev/null`
case $decision in
continuer-la-recherche ) clear ; $0 ;;
arrêter-le-programme )
esac
exit

pour extraire les données d'environ 25 millions de personnes décédés en France depuis 1970
ci-dessous voici le type le données :

HIRT*DAMIEN LOUIS GUILLAUME/                                                    11970022895585SARCELLES                                                   1970031993078127                            
MARIOLI*ELSA MARTINE/                                                           21970030795585SARCELLES                                                   19700509751151281                           
PICHARD*FREDERIC ALBERT ALAIN/                                                  11970031295585SARCELLES                                                   1970050794028722                            
JOUNIAUX*REGIS ROGER JOSE/                                                      11970031795585SARCELLES                                                   1970032295277125                            
LEVI*GHISLAINE LOUISE CLARISSE/                                                 21970032395585SARCELLES                                                   19700721751143036                           
BONNARD*FRANCK/                                                                 11970103195585SARCELLES                                                   19701101940281636                           
BORDALEKOU*PATRICK/                                                             11970031795598SOISY-SOUS-MONTMORENCY                                      1970032995277135     

Comme ça cela n'est pas très claire
Après utilisation du script :

Vous recherchez une personne dénomée : HIRT

	Vous recherchez une personne prénomée : DAMIEN


	Dans : /home/frank/Data_Deces/fichier_deces	sur l'année 1970

1
Nom : HIRT Prenom : DAMIEN LOUIS GUILLAUME	genre : Homme	Date de naissance : 28/02/1970	Lieu : 95585	Commune : SARCELLES
Pays : FRANCE
Date de décès : 19/03/1970	Lieu : 93078	Commune de décès : VILLEPINTE
	acte de décès n° 127




	Il y a 1 résultat(s)

Donc bien plus compréhensible , et la recherche se fait en quelques clics et secondes !
J'aimerai avoir l'avis de personnes aguerries en ce domaine et quelques conseilles pour améliorer mes futurs script
Merci d'avance

modification #1 une fois résolu
Voilà merci à tous pour les conseils, voici mon script modifié, plus de fichier temporaire et correction, simplification :

#!/bin/bash
#-------------------Recherche et extraction de données des fichier.txt www.data.gouv.fr décès entre 1970 et 2021----------------------
#------------------------------------- Auteur Frankkunst / Date 26 janvier 2022 ----------------------------------------------------
err_abandon=100
err_mauvarg=65
err_sanfich=66
presentation () {																				# texte de présentation et info
cat <<eof
			*** NECRODC ***		auteur : Frankkunst		version 02.2022

		Script de recherche des personnes décédées en France entre 1970 et 2021

	Étant prévu pour traiter exclusivement les fichiers .txt fournis sur www.data.gouv.fr, 	la présence des fichiers :

				deces-AAAA.txt	(52 fichiers 1970 à 2021)"

				commune2021.csv

				pays2021.csv

			est indispensable à son fonctionnement

	Selon votre connection internet leurs téléchargement peut s'avérer long ... 5,3 Go

	  Pour continuer appuyer sur "Valider"    Pour abandonner sur "Annuler"
eof
}
declare -ai tablcpt
declare -a tablan=( {1970..2021} )
declare -a tabldecis=( "continuer-la-recherche" "arrêter-le-programme" )
					#--------------------------------* Présentation *-------------------------------------------------------------
zenity --title=INFORMATION --text-info --width="650" --height="450" --filename <(presentation) 2>/dev/null || exit $err_abandon
clear
					#--------------------------------* entrée arguments et contrôle *----------------------------------------------
dossier=$(zenity --file-selection --directory --title="Veuillez choisir le dossier de recherche" 2>/dev/null)
shopt -s nullglob
fichiersINSEE=( "$dossier"/deces-[1-2][0-9][0-9][0-9].txt )
if [ ${#fichiersINSEE[*]} -eq 0 ]
	then
		read -p "Pas de fichier INSEE ! Appuyer sur ENTRER"
		clear
		$0
		exit $err_sanfich
fi
shopt -u nullglob	
annee=$(zenity  --list --text="Veuillez selectionner l'année" --column="ANNEE" ${tablan[*]} 2>/dev/null)
nomprenom=$(zenity --entry --text="NOM	PRENOM	 à rechercher" --width="450" --height="140" 2>/dev/null)
set $nomprenom ; nom=$1 ; prenom=$2
shopt -s extglob
case "$nom" in	      																		# controle format du "NOM"
	+([[:upper:]]) )  echo -e "\v\tVous recherchez une personne dénomée : "$nom ;; 			# controle que le nom soit en majuscule
	* ) clear ; echo -e "\v\v\v\v\v\tVous devez entrer un nom en \e[0;31;01m\"MAJUSCULE\"\e[30;00m uniquement, si c'est un nom composé entrez seulement la première partie\v\v\v\t\t\t"
	read -p "	Appuyer sur ENTRER pour recommencer" ; clear
	$0 ; exit $err_mauvarg
esac
if [ ${#prenom} -ne 0 ]
	then
	case "$prenom" in	      																# controle format du "PRENOM"
		+([[:upper:]]) ) echo -e "\v\tVous recherchez une personne prénomée : "$prenom ;; 	# controle prénom soit en majuscule
		* ) echo -e "\v\v\v\v\v\tVous devez entrer un prénom en \e[0;31;01m\"MAJUSCULE\"\e[30;00m uniquement la première partie \v\v\v\t\t\t"
		read -p "	Appuyer sur ENTRER pour recommencer" ; clear
		$0 ; exit $err_mauvarg
	esac
fi
					#------------------------------------* positionnement dans le dossier *----------------------------------------
cd "$dossier"
echo -n -e "\v\v\tDans : $PWD\tsur l'année $annee\r\v\v"
					#----------------------------* début du travail de recherche dans les fichiers *-------------------------------
suff=.txt
for z in $(ls *"$annee$suff")
do
					#---------------------------------------* recherche donnée *--------------------------------------------
	mapfile tablresult< <(grep -a "^$nom.*$prenom" "$z")
					#----------------------------------------* tri argument *------------------------------------------------------
	n=0																			# amorçage compteur de lignes trouvées
	for i in ${!tablresult[*]}
	do
	n=$[ $n+1 ]
		ligne=${tablresult[i]}
		ligneX=${ligne##*"*"}; indsexe=${ligne:80:1}; j=${ligne:87:2}; m=${ligne:85:2}; a=${ligne:81:4}; com=${ligne:94:30}
		commune=${com%%  *}; pays=${ligne:124:30}; pays1=${pays%% *}
		if [[ $indsexe -eq 1 ]]; then genre="\tgenre :\033[;;46m homme \033[0m"; else genre="\tgenre :\033[;;42m femme \033[0m"; fi
		if [[ ${#pays1} -eq 0 ]]; then paysn=FRANCE; else paysn=$pays; fi
		jdc=${ligne:160:2}; mdc=${ligne:158:2}; adc=${ligne:154:4}; lieuxdc=${ligne:162:5}; act=${ligne:167:9}; acte=${act%% *}
		grep "$lieuxdc" "$dossier"/commune2021.csv >/dev/null; codesortx=$?
		if [[ $codesortx -eq 0 ]]
			then codecomdc=$(grep "$lieuxdc" "$dossier"/commune2021.csv); x=1
			else codecomdc=$(grep "$lieuxdc" "$dossier"/pays2021.csv); x=2
		fi
		IFS=","; set -- $codecomdc
		if [[ $x -eq 1 ]] ; then cdecl=$8 ; else cdecl=$6 ; fi
		echo -n -e "\rNom :"${ligne%%"*"*}"\tPrenom : "${ligneX%%"/"*}  $genre"\tDate de naissance : $j/$m/$a\v\rLieu :"${ligne:89:5}
		echo -e "\tCommune :$commune\tPays :$paysn\v\rDate de décès :$jdc/$mdc/$adc\tLieux de décès :$lieuxdc $cdecl\tacte n°$acte\v"
	done 
	tablcpt[${#tablcpt[*]}]=$n
done
cpt=0
for i in ${!tablcpt[*]}; do (( cpt = $cpt+${tablcpt[i]} )); done
echo -e "\t\t\t\tIl y a \033[;;41m $cpt résultat(s) \033[0m correspondant à la recherche ."
decision=$(zenity --list  --text="Que voulez-vous faire ?" --column="décision" ${tabldecis[*]} 2>/dev/null)
case $decision in
continuer-la-recherche ) clear ; $0 ;;
arrêter-le-programme )
esac
exit 0

C'est plus clair et fonctionnel cool . Le script est passé de 135 lignes à 105 et à gagné en efficacité ! smile

Dernière modification par Frankkunst (Le 04/02/2022, à 19:42)


C'est en forgeant que l'on devient forgerons ...
et
...petit à petit l'oiseau fait son nid !

Hors ligne

#2 Le 28/01/2022, à 15:49

Vobul

Re : [RESOLU]traitement "chaîne de caratères"

Salut,

Tu veux pas poster un gist plutôt ? Perso faire du code review sans coloration syntaxique ni tous les outils modernes (genre numéro de ligne !!) je passe.

Allez juste deux trois trucs vite fait :

- utilise "mkdir -p" pour que ça fonctionne à chaque fois
- utilise shellcheck (c'est un programme qui fait de l'analyse statique)
- utilise des variables en anglais et en ascii

Sinon si ça fonctionne, et ça a l'air d'être le cas, c'est cool !

Allez, tu nous fait le même en python? tongue


Vobul
Utilisez le retour utilisable de commandes !!!
J'aime la langue française, mais je parle franglais, deal with it.
RTFM

Hors ligne

#3 Le 28/01/2022, à 16:09

Frankkunst

Re : [RESOLU]traitement "chaîne de caratères"

Bonjour Vobul
Merci pour ton retour , mais

Vobul a écrit :

Tu veux pas poster un gist plutôt ? Perso faire du code review sans coloration syntaxique ni tous les outils modernes (genre numéro de ligne !!) je passe.

c'est quoi un gist ?... connait pas


C'est en forgeant que l'on devient forgerons ...
et
...petit à petit l'oiseau fait son nid !

Hors ligne

#4 Le 28/01/2022, à 16:41

Watael

Re : [RESOLU]traitement "chaîne de caratères"

for ((y=1;y<=2;y++)); do for ((i=3;i>=1;i--)); do echo "je n'ai rien vu"; done; echo "je ne dis rien, et je ne serai pas banni, encore."; done

Dernière modification par Watael (Le 28/01/2022, à 17:55)


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

Hors ligne

#5 Le 28/01/2022, à 17:27

iznobe

Re : [RESOLU]traitement "chaîne de caratères"

Watael a écrit :
for ((y=1;y<=2;y++)); do for ((i=3;i>=1;i--)); do echo "je n'ai rien vu"; done; echo "je ne dis rien, et je ne serai pas banni, encore."; done; done

Bonjour @Watael , il y a un " ; done" en trop a la fin de ta commande tongue

Dernière modification par iznobe (Le 28/01/2022, à 17:27)


retour COMPLET et utilisable de commande
MSI Z490A-pro , i7 10700 , 32 GB RAM .

Hors ligne

#6 Le 28/01/2022, à 17:55

Watael

Re : [RESOLU]traitement "chaîne de caratères"

corrigé. merci.


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

Hors ligne

#7 Le 28/01/2022, à 20:42

kamaris

Re : [RESOLU]traitement "chaîne de caratères"

Il faudrait remplacer les backticks par $(), et éviter les cat inutiles :

cat f | grep motif -> grep motif f

Il manque quelques guillemets autour des variables aussi, particulièrement lorsqu'il s'agit de chemins (certains autres sont inutiles, mais c'est moins grave).

Hors ligne

#8 Le 29/01/2022, à 05:24

MicP

Re : [RESOLU]traitement "chaîne de caratères"

Bonjour

Dans son script donné dans son message #1, Frankkunst a écrit :
…
E_ABANDON=100
E_MAUVAISARGS=65
E_SANSFICHIER=66
…

Dans un script, il est facile de différencier les variables d'environnement de celles qui ont été créées dans ce script
parce que les noms utilisés pour les variables d'environnement sont toujours en lettres majuscules.

C'est pour ça qu'il vaut mieux éviter de créer des variables dont le nom serait en lettres majuscules.

=======

Dans son script donné dans son message #1, Frankkunst a écrit :
…
mondoss=/home/$USER/TEMPNECRO
mkdir $mondoss
…

Comme on ne sait jamais quelle valeur sera assignée à une variable, et surtout quand il s'agit d'une chaîne de caractères,
il vaut mieux entourer la valeur assignée à la variable ou la variable utilisée dans une commande par des doubles guillemets,
comme ça :

mondoss="/home/$USER/TEMPNECRO"
mkdir "$mondoss"

=======

Dans son script donné dans son message #1, Frankkunst a écrit :
…
declare -a tablan=( 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 )
…

Lance la ligne de commande suivante dans une fenêtre de terminal
juste pour voir ce que ça donne :

echo {1970..2021}

Donc, tu peux remplacer ta ligne de commande
par :

declare -a tablan=( {1970..2021} )

=======

Dans son script donné dans son message #1, Frankkunst a écrit :
…
function fcontroldoss { ls -l "$dossier" | grep -q "deces-[[:digit:]][[:digit:]][[:digit:]][[:digit:]].txt" ; echo $?;}
…

Il vaut mieux déclarer une fonction de la façon suivante :

fcontroldoss() { ls -l "$dossier" | grep -q "deces-[[:digit:]][[:digit:]][[:digit:]][[:digit:]].txt" ; echo $?;}

=======

Dans son script donné dans son message #1, Frankkunst a écrit :
…
if [ $(fcontroldoss) -ne 0 ]														# contole dossier
	then echo -e "\v\v\v\t\tLe dossier \"$dossier\" ne contient pas de fichier INSEE compatible, appuyer sur ENTRER "
		read ; rm $mondoss/tempInfo.txt ; rmdir $mondoss ; clear
		$0 ; exit $E_SANSFICHIER
fi
…

pourrait être présenté de la façon suivante :

if [ $(fcontroldoss) -ne 0 ]; then                                                                                                       # contole dossier
    echo -e "\v\v\v\t\tLe dossier \"$dossier\" ne contient pas de fichier INSEE compatible, appuyer sur ENTRER"
    read
    rm "$mondoss/tempInfo.txt"
    rmdir "$mondoss"
    clear
    $0
    exit "$E_SANSFICHIER"
fi

=======
Toutes les propositions de solution que j'ai faites dans ce message
sont encore à améliorer et à corriger.

Voir aussi : wiki.bash-hackers -> Scripting with style

Il y a plein de liens vers des tutos et conseils dans la page web : https://wiki.bash-hackers.org/start

Dernière modification par MicP (Le 29/01/2022, à 05:40)

Hors ligne

#9 Le 29/01/2022, à 07:07

Watael

Re : [RESOLU]traitement "chaîne de caratères"

non, pas ls | grep.
plutôt un tableau :

fichiersINSEE=( "$dossier"/deces-[0-9][0-9][0-9][0-9].txt )
# et on teste son nombre d'éléments
(( ${#fichiersINSEE[*]} )) || errQuit "pas de fichiers INSEE"
presentation () {
cat <<eof
bla bla...

Pour continuer appuyer sur "Valider"    Pour abandonner sur "Annuler"
eof
}
zenity --title=INFORMATION --text-info --width="650" --height="450" --filename <(presentation)

et hop! un fichier temporaire inutile en moins.

mais bon, le temps qu'on ait épluché toutes les maladresses de ce script, Frankkunst l'aura probablement réécrit correctement, avec en ayant pensé un algorithme robuste au préalable.

Dernière modification par Watael (Le 29/01/2022, à 07:09)


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

Hors ligne

#10 Le 29/01/2022, à 10:00

Frankkunst

Re : [RESOLU]traitement "chaîne de caratères"

Bonjour ,
Je vous remercie bien pour tous ces conseils, je teste et reviens vite vers vous .

Watael a écrit :

mais bon, le temps qu'on ait épluché toutes les maladresses de ce script, Frankkunst l'aura probablement réécrit correctement, avec en ayant pensé un algorithme robuste au préalable

Il y a tant de maladresses que ça !? ...Bon à apprendre à la petite semaine, sans aide, l'écriture Bash n'est pas évidente à cerner !
J'ai compris, il y a encore du boulot wink


C'est en forgeant que l'on devient forgerons ...
et
...petit à petit l'oiseau fait son nid !

Hors ligne

#11 Le 29/01/2022, à 10:28

Frankkunst

Re : [RESOLU]traitement "chaîne de caratères"

Merci bien,

Micp a écrit :

declare -a tablan=( {1970..2021} )

et cela fonctionne top ! cool
C'est le style de syntaxe qui me manque bien, j'ai eu beau chercher, la doc est assez laconique !
Bon j'ai déjà modifié ça, + les guillemets pour les variables
Pour l'initialisation des variables en majuscule j'ai suivi les exemples donnés dans les manuels de langage bash ... donc bien pas bien ?...Il doit y avoir plusieurs écoles roll
Bon je continu d'améliorer ça smile


C'est en forgeant que l'on devient forgerons ...
et
...petit à petit l'oiseau fait son nid !

Hors ligne

#12 Le 29/01/2022, à 10:41

Watael

Re : [RESOLU]traitement "chaîne de caratères"

Il doit y avoir plusieurs écoles

non.
simplement, tout ce qu'on trouve sur le net n'est pas vrai.
certains font des "tutos" en copiant les erreurs que d'autres ont probablement copiées avant eux.
finalement, on trouve encore des "tutos" récents qui montrent des boucles for sur des Substitutions de commandes. roll


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

Hors ligne

#13 Le 29/01/2022, à 10:44

MicP

Re : [RESOLU]traitement "chaîne de caratères"

On trouve de tout sur internet : le meilleur,
et malheureusement, le pire aussi.

=======

… j'ai eu beau chercher, la doc est assez laconique ! …

Au début, on a l'impression de passer un temps fou à lire des trucs qui ne servent à rien,
puis, petit-à petit, tout devient de plus en plus logique, et tout ce qu'il nous semblait avoir lu "pour rien" nous permet de mieux comprendre que rien n'a été ni oublié, ni en trop : tout est utile.
C'était simplement parce que ce n'était pas ce que l'on espérait trouver sur le moment.

=======
On passe beaucoup de temps à lire les manuels des commandes en utilisant la commande man

Un des premier manuel à lire est nommé … intro

man intro

Pour voir les pages du manuel concernant l'interpréteur de commande bash,
c'est :

man bash

Hors ligne

#14 Le 29/01/2022, à 10:45

Watael

Re : [RESOLU]traitement "chaîne de caratères"

Il doit y avoir plusieurs écoles

non.
simplement, tout ce qu'on trouve sur le net n'est pas vrai.
certains font des "tutos" en copiant les erreurs que d'autres ont probablement copiées avant eux. mad
la preuve, tu y a trouvé qu'une Substitution de commandes se fait entre des ` `, alors qu'il y a plus de vingt qu'ils ont été abandonnés dans la pratique, et ne sont conservés que pour permettre à des vieux scripts de fonctionner encore.
et finalement, on trouve encore des "tutos" récents qui montrent des boucles for sur des Substitutions de commandes. roll


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

Hors ligne

#15 Le 29/01/2022, à 13:41

Frankkunst

Re : [RESOLU]traitement "chaîne de caratères"

Dans le poste #9

Watael a écrit :
presentation () {
cat <<eof
bla bla...

Pour continuer appuyer sur "Valider"    Pour abandonner sur "Annuler"
eof
}
zenity --title=INFORMATION --text-info --width="650" --height="450" --filename <(presentation)

et hop! un fichier temporaire inutile en moins.

c'est bien ce type d'astuce que je pensais utiliser, mais la commande zenity option --filename attend un fichier !?...
Donc cela ne fonctionne pas . sad


C'est en forgeant que l'on devient forgerons ...
et
...petit à petit l'oiseau fait son nid !

Hors ligne

#16 Le 29/01/2022, à 13:51

Watael

Re : [RESOLU]traitement "chaîne de caratères"

j'ai testé avant de poster. la syntaxe <(...) "redirige" vers un descripteur de fichier, qui est un fichier.

$ cat <(echo "bla bla")
bla bla

pourtant, cat aussi attend un fichier comme argument. smile


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

Hors ligne

#17 Le 29/01/2022, à 17:48

Frankkunst

Re : [RESOLU]traitement "chaîne de caratères"

Ok pour cat, si tu fais :

presentation () {
cat <<eof
bla bla...

Pour continuer appuyer sur "Valider"    Pour abandonner sur "Annuler"
eof
}
echo $(presentation)

pas de problème mais avec zenity cela ne fonctionne pas !
Les commandes l'une après l'autre dans le terminal fonctionne mais en passant par un script, que voici :

#!/bin/sh
presentation () {
cat <<eof
bla bla...

Pour continuer appuyer sur "Valider"    Pour abandonner sur "Annuler"
eof
}
zenity --title=INFORMATION --text-info --width="650" --height="450" --filename <(presentation)
exit

voilà le résultat :

frank@ordiport:~/bin$ testPresent
/home/frank/bin/testPresent: 9: /home/frank/bin/testPresent: Syntax error: "(" unexpected
frank@ordiport:~/bin$

Alors, que envoyer l'une après l'autre :

frank@ordiport:~$ presentation () {
> cat <<eof
> bla bla...
> 
> Pour continuer appuyer sur "Valider"    Pour abandonner sur "Annuler"
> eof
> }
frank@ordiport:~$ zenity --title=INFORMATION --text-info --width="650" --height="450" --filename <(presentation)
Gtk-Message: 17:17:02.632: GtkDialog mapped without a transient parent. This is discouraged.
frank@ordiport:~$

et j'ai bien la fenêtre zenity qui s'ouvre !... bon avec son message erreur habituel que l'on élimine avec un 2>/dev/null
Un autre problème qui se pose si j'arrive à faire fonctionner cette commande dans le script, c'est la présentation
Je n'arrive pas à garder la mise en page que je souhaite comme avec le fichier hmm

Dernière modification par Frankkunst (Le 29/01/2022, à 18:34)


C'est en forgeant que l'on devient forgerons ...
et
...petit à petit l'oiseau fait son nid !

Hors ligne

#18 Le 29/01/2022, à 18:12

Frankkunst

Re : [RESOLU]traitement "chaîne de caratères"

Une autre question

Watael a écrit :

tu y a trouvé qu'une Substitution de commandes se fait entre des ` `, alors qu'il y a plus de vingt qu'ils ont été abandonnés dans la pratique, et ne sont conservés que pour permettre à des vieux scripts de fonctionner encore

par quoi remplacer les ` ` ???


C'est en forgeant que l'on devient forgerons ...
et
...petit à petit l'oiseau fait son nid !

Hors ligne

#19 Le 29/01/2022, à 18:33

Frankkunst

Re : [RESOLU]traitement "chaîne de caratères"

Sinon pour avancer en langage bash, j'ai utilisé surtout deux support :
- une introduction à la programmation en Bash de Eric Sanchis de 2007
- le Guide avancé d'écriture des scripts Bash version 5.2 de Mendel Cooper de 2008
J'ai justement privilégié les cours structurés et évité de prendre des infos à droite et à gauche .
Sachant justement que sur internet on trouve de tout, je ne suis pas né de la dernière pluie ... j'ai commencé à utiliser les ordis depuis 1985, toujours intéressé au fonctionnement de ce que j'utilise, à temps perdu j’approfondis mes connaissances .
Donc si quelqu'un à un lien sur lequel je peux télécharger un cours sérieux  et récent, je suis preneur ! smile smile smile


C'est en forgeant que l'on devient forgerons ...
et
...petit à petit l'oiseau fait son nid !

Hors ligne

#20 Le 29/01/2022, à 18:47

Watael

Re : [RESOLU]traitement "chaîne de caratères"

là, tu as ce qu'il faut : l'ABS.

ensuite, il faut pratiquer pour savoir utiliser le shell et ses subtilités, et pratiquer, et pratiquer...
mettre en œuvre chaque nouvelle notion sur des petits projets, des petites choses qui te facilitent la vie au quotidien dans le terminal.

il faut prévoir ce qu'il y a à faire, avant de coder (en pseudo code éventuellement), pour éviter les répétitions, les digressions et les détours. Ce que j'appelle "penser un algorithme robuste".
il y a une entrée, et tu sais quelle sortie tu veux.
entre les deux, il faut prévoir toutes les opérations, et les conditions qui déclencheront telle ou telle opération, en gardant à l'esprit ce principe essentiel : KISS! (Keep It Simple Stupid!)

et, si ce n'est pas KISS, c'est Kloug !
lol

Dernière modification par Watael (Le 29/01/2022, à 18:50)


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

Hors ligne

#21 Le 29/01/2022, à 19:25

ar barzh paour

Re : [RESOLU]traitement "chaîne de caratères"

ma petite pierre
@FrankKunst
essaie en mettant #!/bin/bash au lieu de #!/bin/sh dans testPresent.sh

`` remplacées par $()

des doc
http://www.gnu.org/software/bash/manual/bash.html
https://abs.traduc.org/abs-fr/

Dernière modification par ar barzh paour (Le 29/01/2022, à 20:04)


PC          : B760M DS3H DDR4,  12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 20.04, 22.04, 24.04 (en test )
Portable1 : ThinkPad P50 I7-6820HQ, 16G0 Ram Ubuntu 22.04 Ubuntu 24.04 , W10-PRO( en voyage )
Portable2 : T5750  @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )

Hors ligne

#22 Le 29/01/2022, à 19:35

Frankkunst

Re : [RESOLU]traitement "chaîne de caratères"

Bonsoir Watael, Kamaris, MicP
Pour les `  ` , j'ai trouvé la solution $(groupe de commande...) et le script fonctionne bien ; donc la solution de Kamaris en #7 et suivi le conseil pour les " " autour des variables .
J'ai utilisé la solution de MicP en #8   declare -a tablan=( {1970..2021} ) pour le tableau, qui est bien moins fastidieuse à écrire smile
Merci déjà beaucoup, j’essaie d'améliorer encore ce script et de l'éclaircir , puis je le reposte cool


C'est en forgeant que l'on devient forgerons ...
et
...petit à petit l'oiseau fait son nid !

Hors ligne

#23 Le 29/01/2022, à 19:40

Frankkunst

Re : [RESOLU]traitement "chaîne de caratères"

ar barzh paour a écrit :

ma petite pierre
@FrankKunst
essaie en mettant #!/bin/bash au lieu de #!/bin/sh dans testPresent.sh

`` remplacées par $()

merci bien, n'étant pas très au fait de votre langage je n'avais pas compris le poste #7 de MicP, mais maintenant c'est oK pour ça cool


C'est en forgeant que l'on devient forgerons ...
et
...petit à petit l'oiseau fait son nid !

Hors ligne

#24 Le 29/01/2022, à 22:21

MicP

Re : [RESOLU]traitement "chaîne de caratères"

Dans son message #21, ar barzh paour a écrit :

… essaie en mettant #!/bin/bash au lieu de #!/bin/sh dans testPresent.sh …

Alors Oui, ça, c'est très important
parce que c'est en fonction de ça que sera déterminé le nom de l'interpréteur de commandes
qui va être utilisé pour interpréter et exécuter toutes les lignes de commandes qui seront contenue dans le script.

Et ce qui t'es arrivé, Frankkunst
c'est qu'en mettant

#!/bin/sh

quand tu as voulu ensuite lancer ton script,
c'est un autre interpréteur de commande qui a été utilisé pour interpréter les lignes de commandes contenues dans le script
alors que les lignes de commandes contenues dans ton script avaient été rédigées pour être interprétées par /bin/bash

Dernière modification par MicP (Le 29/01/2022, à 22:34)

Hors ligne

#25 Le 30/01/2022, à 09:48

Frankkunst

Re : [RESOLU]traitement "chaîne de caratères"

Merci bien MicP, je n'avais pas bien porté attention à la remarque

du poste #21 de ar barzh paour a écrit :

… essaie en mettant #!/bin/bash au lieu de #!/bin/sh dans testPresent.sh …

comme tu le dis

MicP a écrit :

c'est un autre interpréteur de commande qui a été utilisé pour interpréter les lignes de commandes contenues dans le script
alors que les lignes de commandes contenues dans ton script avaient été rédigées pour être interprétées par /bin/bash

Et c'est effectivement primordial
On va dire que c'est une erreur de jeunesse wink


C'est en forgeant que l'on devient forgerons ...
et
...petit à petit l'oiseau fait son nid !

Hors ligne