# \[Bash\] Ligne pair/impair

**URL:** <https://www.debian-fr.org/t/bash-ligne-pair-impair/28885>\
**Category:** Programmation\
**Created:** [Février 20, 2016, 11:37 UTC](https://www.debian-fr.org/t/bash-ligne-pair-impair/28885 "2016-02-20T23:37:45Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![CrystalShip](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/c/a698b9/32.png) [@CrystalShip](https://www.debian-fr.org/u/CrystalShip)\
**Post date:** [Février 20, 2016, 11:37 UTC](https://www.debian-fr.org/t/bash-ligne-pair-impair/28885/1 "2016-02-20T23:37:45Z")

</div>

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

```auto
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 😃

---

<div class="post-metadata">

**Author:** ![BBT1](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/b/ecc23a/32.png) [@BBT1](https://www.debian-fr.org/u/BBT1)\
**Post date:** [Février 20, 2016, 11:37 UTC](https://www.debian-fr.org/t/bash-ligne-pair-impair/28885/2 "2016-02-20T23:37:46Z")

</div>

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 :

> [@](#):
>
> rajouter |toto à la fin

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 ‹&nbsp;$&nbsp;› devant le nom de la variable,  
qui sera alors remplacée par sa valeur.

Attention :

- ‹&nbsp;|&nbsp;› 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.

```auto
Syntaxe : echo <chaine1> <chaine2> ... <chaine n>
```

> [@](#):
>
> lignes pair, rajouter |toto à la fin, pour les lignes impair, rajouter |tata à la fin.

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 😉

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 11:37 UTC](https://www.debian-fr.org/t/bash-ligne-pair-impair/28885/3 "2016-02-20T23:37:54Z")

</div>

Belle explication 🙂

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

```auto

```

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

```auto

```

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

```auto

```

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.

---

<div class="post-metadata">

**Author:** ![CrystalShip](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/c/a698b9/32.png) [@CrystalShip](https://www.debian-fr.org/u/CrystalShip)\
**Post date:** [Février 20, 2016, 11:37 UTC](https://www.debian-fr.org/t/bash-ligne-pair-impair/28885/4 "2016-02-20T23:37:55Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Totor](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/t/58f4c7/32.png) [@Totor](https://www.debian-fr.org/u/Totor)\
**Post date:** [Février 20, 2016, 11:38 UTC](https://www.debian-fr.org/t/bash-ligne-pair-impair/28885/5 "2016-02-20T23:38:17Z")

</div>

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 :

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

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 11:38 UTC](https://www.debian-fr.org/t/bash-ligne-pair-impair/28885/6 "2016-02-20T23:38:17Z")

</div>

[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.

---

<div class="post-metadata">

**Author:** ![CrystalShip](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/c/a698b9/32.png) [@CrystalShip](https://www.debian-fr.org/u/CrystalShip)\
**Post date:** [Février 20, 2016, 11:38 UTC](https://www.debian-fr.org/t/bash-ligne-pair-impair/28885/7 "2016-02-20T23:38:26Z")

</div>

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. 😃
