# Supprimer lignes avec caractère identiques avant modèle

**URL:** <https://www.debian-fr.org/t/supprimer-lignes-avec-caractere-identiques-avant-modele/73134>\
**Category:** Programmation\
**Created:** [Avril 1, 2017, 2:59 UTC](https://www.debian-fr.org/t/supprimer-lignes-avec-caractere-identiques-avant-modele/73134 "2017-04-01T14:59:18Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![tarof](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/t/49beb7/32.png) [@tarof](https://www.debian-fr.org/u/tarof)\
**Post date:** [Avril 1, 2017, 2:59 UTC](https://www.debian-fr.org/t/supprimer-lignes-avec-caractere-identiques-avant-modele/73134/1 "2017-04-01T14:59:18Z")

</div>

Bonjour,

Voici mon problème.

Je possède un fichier texte comprenant de nombreuses lignes identiques mais ne finissant pas de la même façon. La fin de chaque ligne finie par un point virgule suivit d’une date.  
J’aimerais supprimer les lignes identiques en ne gardant uniquement celles qui contiennent la date la plus récente.

Exemple:

voici le fichier input

```
aaa ;2010:05:24
aaa ;2011:02:23
aaa ;2012:01:25
bbb ;2010:02:03
bbb ;2015:04:12
bbb ;2013:03:12
bbb ;2014:06:07
ccc ;2011:05:02
ccc ;2008:09:21

```

voici à quoi j’aimerais que le fichier output ressemble:

```
aaa ;2012:01:25
bbb ;2015:04:12
ccc ;2011:05:02

```

J’ai bien sur penser à utiliser sed, mais je bloque pour comparer les caractères uniquement avant le point virgule et pas toute la ligne puis pour lui faire garder celle avec la date la plus récente.

Je m’en remets à vous 🙏

---

<div class="post-metadata">

**Author:** ![josephtux](https://www.debian-fr.org/user_avatar/www.debian-fr.org/josephtux/32/3985_2.png) [@josephtux](https://www.debian-fr.org/u/josephtux)\
**Post date:** [Avril 1, 2017, 5:30 UTC](https://www.debian-fr.org/t/supprimer-lignes-avec-caractere-identiques-avant-modele/73134/2 "2017-04-01T17:30:54Z")

</div>

> for i in aaa bbb ccc; do egrep ^«&nbsp;${i}&nbsp;» fichier\_a\_filtrer.txt | sort | tail -1 \>\> fichier\_resultat.txt; done

En bash, les pipes sont souvent une meilleure solution

1- Sélectionner les lignes à filtrer (boucle for, filtre egrep)  
2- Trier tout simplement avec sort  
C’est facile car la format de la date est adapté: année, mois, jour.  
3- Extraire le premier élément avec tail -1

---

<div class="post-metadata">

**Author:** ![tarof](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/t/49beb7/32.png) [@tarof](https://www.debian-fr.org/u/tarof)\
**Post date:** [Avril 1, 2017, 6:11 UTC](https://www.debian-fr.org/t/supprimer-lignes-avec-caractere-identiques-avant-modele/73134/3 "2017-04-01T18:11:12Z")

</div>

> [@josephtux](#):
>
> > for i in aaa bbb ccc; do egrep ^«&nbsp;${i}&nbsp;» fichier\_a\_filtrer.txt | sort | tail -1 \>\> fichier\_resultat.txt; done

le souci avec le code que tu propose c’est qu’on obligé de nommer les lignes duppliqués.  
Hors le fichier en question contient 14K lignes dont environ 4000 sont différentes les unes des autres.

---

<div class="post-metadata">

**Author:** ![Watael](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/w/a4c791/32.png) [@Watael](https://www.debian-fr.org/u/Watael)\
**Post date:** [Avril 1, 2017, 7:14 UTC](https://www.debian-fr.org/t/supprimer-lignes-avec-caractere-identiques-avant-modele/73134/4 "2017-04-01T19:14:05Z")

</div>

salut,

```auto
sort -rV -t ';' -k2 fichier | sort -u -k1,1

```

---

<div class="post-metadata">

**Author:** ![tarof](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/t/49beb7/32.png) [@tarof](https://www.debian-fr.org/u/tarof)\
**Post date:** [Avril 1, 2017, 10:39 UTC](https://www.debian-fr.org/t/supprimer-lignes-avec-caractere-identiques-avant-modele/73134/5 "2017-04-01T22:39:40Z")

</div>

> [@Watael](#):
>
> salut,
> 
> ```auto
> sort -rV -t ';' -k2 fichier | sort -u -k1,1
> 
> ```

Cette commande marche bien pour mon exemple,  
néanmoins sur mon fichier réel cela n’affiche que deux lignes.

En essayant la première partie, soi juste le tri

`sort -rV -t ';' -k2 fichier`

tout est ok jusque là, les fichiers ont bien été trié par date.

Mais si je fais ensuite

`sort -u -k1,1 fichier`

Il ne me reste que deux lignes sur les 4000 qui devraient être présente.

En testant un peu j’ai essayer ça  
`sort -u -t ';' -k1,1 fichier`

Cela semble avoir fonctioné 🙂

Merci bien.

---

<div class="post-metadata">

**Author:** ![josephtux](https://www.debian-fr.org/user_avatar/www.debian-fr.org/josephtux/32/3985_2.png) [@josephtux](https://www.debian-fr.org/u/josephtux)\
**Post date:** [Avril 2, 2017, 11:54 UTC](https://www.debian-fr.org/t/supprimer-lignes-avec-caractere-identiques-avant-modele/73134/6 "2017-04-02T11:54:04Z")

</div>

Enchainer 2 «sort»; bravo les pros (et merci)

Pourquoi -V ? (j’avoue n’avoir pas tout compris des différents modes de tri expliqués [ici](https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html#sort-invocation).)

---

<div class="post-metadata">

**Author:** ![josephtux](https://www.debian-fr.org/user_avatar/www.debian-fr.org/josephtux/32/3985_2.png) [@josephtux](https://www.debian-fr.org/u/josephtux)\
**Post date:** [Avril 2, 2017, 12:58 UTC](https://www.debian-fr.org/t/supprimer-lignes-avec-caractere-identiques-avant-modele/73134/7 "2017-04-02T12:58:19Z")

</div>

Autre précision que je découvre: l’option _-u_ de _sort_ n’agit que sur le champs de tri (si j’ai bien compris, sans évoquer l’histoire de l’option -c ou -C ou --check), alors que la commande _uniq_ agirait sur toute la ligne, ce qui permet d’éviter le _tail_ de ma commande à rallonge.
