Commande pour écrire dans un fichier.txt par ordre alphabétique

Salut :slight_smile:

J’édite un scrip qui référence les informations dans un fichier.txt. Je cherche depuis à un moment à les éditer automatiquement par ordre alphabétique mais rien n’apporte de solution, peut être awk s’il est bien utilisé mais rien ne me saute au yeux.

Voici un exemple de mon fichier.txt

--------------------

nom : abricot
description : mange un abricot

--------------------

nom : pomme
description : coupe une pomme

Je voudrais que si je créer le script banane, il soit édité entre les deux précédent, et non à la suite comme il se fait actuellement, et donne ceci

--------------------

nom : abricot
description : mange un abricot

--------------------

nom : banane
description : épluche une banane

--------------------
nom : pomme
description : coupe une pomme

Merci pour votre aide.

Tu peux balancer les lignes de ton ‹ fruit › ici même que l’on voie comment tu cherche à trier le contenu de ton fichier TXT.

Te rends tu compte que tu ne précise me^me pas dans quel langage tu cherche à faire ton tri ?

2 J'aime

Salut Clochette,

Excuse moi pour le manque de précision, le bash est une option évidents pour moi mais j’ai tendance à oublier que debian ne rime pas qu’avec bash.

Pour mon script voici un extrait :

  if test ! -f "/home/tommy/created_commands"

 	then

	touch /home/tommy/created_commands

 fi

 echo -e "------------------------\n" >> /home/tommy/created_commands
 echo "name : $scnm" >> /home/tommy/created_commands
 echo -e "description : $scds\n" >> /home/tommy/created_commands

Il n’a pas d’argument pour justifier le classement alphabétique. Mes recherches me renvoient souvent vers sort mais rien qui m’avance.

Merci.

Bonjour

Il y a sans aucun doute des personnes plus compétentes qui pourraient proposer
une solution plus élégante, mais en attendant …

fichOut="/home/tommy/created_commands"
lignSep="------------------------"

echo -e "$lignSep\nname : $scnm\ndescription : $scds\n" >> "$fichOut"

sed "/^-*$/d;N;s/\n/ /" "$fichOut" | sort |                      \
sed "s/\(description :\)/\n\1/;s/\(nom :\)/\n$lignSep\n\n\1/" |  \
sed "1d" >>fichTmp && mv -f fichTmp "$fichOut"

EDIT : Script corrigé


La partie suivante de ton script était inutile.

if test ! -f "/home/tommy/created_commands"

 	then

	touch /home/tommy/created_commands

 fi
1 J'aime

Salut,

Effectivement le script classe les infos par ordre alphabétique mais il les édite à la suite dans le fichier. J’ai creuser du côté de la commande sed, avec sed -i mais je ne vois rien de fonctionnel. Mais je retiens le script donné, je pense qu’il peut être bien utile.

Désolé,
je n’avais pas recopié la ligne entière, il manquait la fin.
Je viens de corriger le script de mon précédent message

Sous bash, la commande de tri est : sort. Peut-être creuser de ce coté, mais je ne suis pas sur d’avoir compris toute la question.

Par exemple:
Le principe:
grep "^nom :" fichierfruits.txt | sort

et pour avoir la description:
grep -A1 "^nom :" fichierfruits.txt | sed s/$/<Ctrl-V Ctrl-M/ | sort

(ou qq chose comme ça, je n’ai pas le temps de tester la commande sed pour concaténer les lignes)

Il me semble que grep sert plutôt à chercher une chaîne de caractère, mais la deuxième commande m’affiche -bash: Ctrl-V: No such file or directory.

J’ai bien regardé ton script MicP, mais à quoi fait référence fichTmp ?

fichTmp est le nom d’un fichier qui sera créé par la sortie de la commande sed
et qui sera renommé juste après pour remplacer le fichier de sortie $fichOut


Il fallait taper successivement les raccourcis claviers Ctrl-V et Ctrl-M

C’est ce que fait la première commande sed de ma proposition de script :

michel@debT450:~$ cat  fichier
--------------------

nom : abricot
description : mange un abricot

--------------------

nom : pomme
description : coupe une pomme
michel@debT450:~$ 
michel@debT450:~$ sed "/^-*$/d;N;s/\n/ /" fichier
nom : abricot description : mange un abricot
nom : pomme description : coupe une pomme
michel@debT450:~$ 

Mais peut-être que Linuxy n’a pas entièrement recopié la dernière ligne de commandes de ma proposition de script,
ligne de commande que j’ai scindée en 3 lignes en utilisant le caractère \ qui est à la fin des deux premières lignes

sed "/^-*$/d;N;s/\n/ /" "$fichOut" | sort |  sed "s/\(description :\)/\n\1/;s/\(nom :\)/\n$lignSep\n\n\1/" |  sed "1d" >>fichTmp && mv -f fichTmp "$fichOut"

est équivalent, (en scindant en 3 lignes l’unique ligne de commandes ci-dessus) à :

sed "/^-*$/d;N;s/\n/ /" "$fichOut" | sort |                      \
sed "s/\(description :\)/\n\1/;s/\(nom :\)/\n$lignSep\n\n\1/" |  \
sed "1d" >>fichTmp && mv -f fichTmp "$fichOut"

salut
à mon avis, tu devrais utiliser la logique d’une base de données
concrètement, tout sur une ligne
ensuite un tri devient super facile par exemple avec | sort

et si tu as besoin d’afficher en plusieurs lignes tu prends ton fichier de données et tu affiches par exemple avec | tr « ; » « \n »

Oui, je pense aussi que c’est ce qu’il aurait mieux valu faire,
mais comme on ne voit pas le début du script,
dans lequel les variables scnm et scds ont été créées,
J’ai juste fait la ligne de script suivante
qui réordonne le contenu du fichier de sortie tout en conservant sa présentation :

et comme elle est un peut trop longue,
pour qu’elle soit plus présentable,
avec le caractère \
j’ai scindé cette unique ligne de commandes en trois lignes,
ce qui donne :

sed "/^-*$/d;N;s/\n/ /" "$fichOut" | sort |                      \
sed "s/\(description :\)/\n\1/;s/\(nom :\)/\n$lignSep\n\n\1/" |  \
sed "1d" >>fichTmp && mv -f fichTmp "$fichOut"

Salut,

J’avais mis un peu ce sujet en stand by, pris par un sujet en parrallèle.

Pour avoir une vu d’ensemble voici le scrip complet :

#!/bin/bash

# The command create a script

#---------------Verify if file exist---------------

 while true

 do

 read -p "Enter script name : " scnm

 	if [ -f "/usr/bin/$scnm" ]

		then

		  echo "error: this script already exist."

	elif [ -f "/usr/sbin/$scnm" ]

		then

		  echo "error: this script already exist."

#----------------Create the script---------------

	else

		while true

		do

		read -p "Command must be run as root ? [Y/n] " reply

			case $reply in

		 	 Y|y|Yes|yes) filesc="/usr/sbin/$scnm"
			              break ;;

			   N|n|No|no) filesc="/usr/bin/$scnm"
			              break ;;

		 	           *) echo "error: invalid reply, please retry." ;;
				
			esac

		done

 		  read -p "Enter script description : " scds

 		  touch $filesc

		  chmod +x $filesc

#----------Edit file informations in created_commands----------

 		   fileref="/home/tommy/.created_commands"
		   linesep="------------------------"

 		  echo -e "$linesep\nname : $scnm\ndescription : $scds\n" >> "$fileref"

#----------Edit automatically beginning of the script----------

 		  echo -e "#!/bin/bash\n" >> $filesc
		  echo -e "# $scds\n" >> $filesc

 		  nano $filesc

		break
	fi

done

Voilà l’utilité de référencer les scripts par ordre alphabétique, je les classe ditectement dans bin ou sbin donc par soucis d’organisation je les référence dans un fichier home mais par confort je (et pour mieux me familiariser avec la programmation) je tenais à ce que ce soit par ordre alphabétique.

J’ai testé les solutions donnés mais bien que chacun men apprenne plus sur la programmation, il n’y en a pas qui me permette à arriver à mes fins ou me mette sur la voie.

Merci pour l’aide que vous m’apportez, je souhaite à tout le monde une agréable soirée.

Tu fait une confusion. La différence entre /sbin et /bin n’a rien à voir avec le fait d’être root ou user.

/sbin sont les binaires systèmes essentiels (pour **tous** les utilisateurs)
/bin sont les binaires de commandes utilisateurs essentiels (pour **tous** les utilisateurs)

Et de fait, on évite d’y mettre n’importe quoi comme le fait ton script.
Si tu veux créer des script /bin ou /sbin c’est dans /usr/local/bin et /usr/local/sbin qu’il faudrait les mettre.