[Bash] Ligne pair/impair

Salut, j’aimerais pouvoir travailler chaque ligne d’un fichier en tenant compte du fait des lignes pair et impair.

while read LINE
do
	
	?????

done < "$HOME/test.txt"

Ce que j’aimerais, c’est rajouter des informations à la fin de chaque ligne. Pour faire simple, pour les lignes pair, rajouter |toto à la fin, pour les lignes impair, rajouter |tata à la fin.

Voila voila, merci d’avance :smiley:

Bon comme ça ressemble à un exercice je ne vais pas te donner la réponse directement,
mais je peux te donner des clés pour que tu puisses te lancer :

Pour concaténer une chaîne au contenu d’une variable,
il suffit d’évaluer la variable et de mettre la chaîne tout de suite après.

Pour évaluer une variable il suffit de placer ‘$’ devant le nom de la variable,
qui sera alors remplacée par sa valeur.

Attention :

  • ‘|’ est un caractère spécial pour le shell, il faut donc le protéger

Pour protéger un caractère en shell, on peut le préfixer par ‘’.

La commande pour afficher une chaîne de caractère est echo.

Pour distinguer les lignes paires des lignes impaires,
tu as besoin d’un état, c’est à dire une variable qui te permet de savoir là où tu en est.

Dans notre cas, il n’y que deux états : pair et impair.
Pour les distinguer tu as donc besoin d’une variable qui te permet de savoir si la ligne précédente
était paire ou impaire, un test pour savoir si tu dois rajouter tata ou toto
et une affectation pour changer la valeur de la variable.

En pseudo code :

ETAT="impair" tant que j'ai des ligne LIGNE à lire dans mon fichier si ETAT == "impair" alors <traitement 1> ETAT="pair" sinon /* implicitement on a ETAT == "pair" <traitement 2> ETAT="impair" fin_si fin_tant_que

Syntaxe du if en shell :

if <commande>; then <traitement 1> else <traitement 2> fi
Syntaxe d’un test d’égalité de chaine de caractère :
[ chaine1 = chaine2 ]
qui renvoie vrai ou faux (et n’affiche rien)

Voilà je pense que tu as tous les outils à disposition pour résoudre ton exercice :wink:

Belle explication :slight_smile:

Maintenant amusons nous. Avec awk on ne s’embête pas a écrire la boucle de lecture :

Ensuite on peut utiliser sed qui est pas mal pour ça (et il gagne même le concourt de golf) :

Edit: J’avais mal lu l’énoncé donc en sed :

Pas testé mais ça devrais fonctionner. Ca m’auras permis de découvrir l’adressage N~M de sed qui peut être très pratique.

Merci à vous deux, j’ai réussi à faire ce que je voulais :smiley:

Maintenant que tu as ta solution…
voilà comment je procéderai :

#!/bin/bash i=1 t=("titi" "tata") while read do ((i=1-i)) # ou ((i=i^1)) echo "${REPLY}|${t[i]}" done < fichier

Pour le awk :

awk 'BEGIN {t[0]="titi"; t[1]="tata"} { print $0 "|" t[NR%2] }' fichier

[quote=“Totor”]Pour le awk :

awk 'BEGIN {t[0]="titi"; t[1]="tata"} { print $0 "|" t[NR%2] } fichier [/quote]
Tu as raison c’est la solution la plus jolie quand on l’a lu l’énoncé jusqu’au bout (ce qui n’était pas mon cas).
Après trouver un cas d’utilisation à ce genre de commande ne doit vraiment pas être trivial.

Juste pour info, c’était pas du tous un exercice où je ne sais quoi, c’est pour un script perso. Dans tous les cas vous m’avez appris des choses merci. :smiley: