Nettoyage et remplacement lignes d'un fichier via SED, AWK ou autre.

Résolu/Fermé
pcsystemd Messages postés 691 Date d'inscription dimanche 27 novembre 2005 Statut Membre Dernière intervention 15 janvier 2024 - Modifié le 19 oct. 2021 à 17:46
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 - 19 oct. 2021 à 17:59
Bonjour,

J'ai un fichier avec des centaines de lignes de ce type. Exemple avec 2 lignes sachant que chaque ligne commence par "252_

"252_2773 | O² , Cabet  , Sa Gein ye | SA,738-654 5163,289,1 596,""18,11"",""1,05"",""190,44"",""303,94"""
"252_9083 | O² , I. Imiler, Chf-uone | SA,885-417-0377,227,906,""25,06"",""0,80"",""201,29"",""182,37"""


Je souhaiterais supprimer toutes les doubles côtes et mettre comme séparateur un ; a la place de la virgule mais ATTENTION que les virgules qui servent de séparateur pas les virgules qui sépare les décimales des nombres exemple 303,94 et pas les virgules qui font partie du texte (premier champ) et l'exemple 252_2773 | O² , Cabet , Sa Gein ye | SA

Le résultat souhaité est :

Come;Nuro clnt;Cls;Ions;CT;CC mo.;CM mo.;Coûtrty
252_2773 | O² , Cabet  , Sa Gein ye | SA;738-654-5163;289;1 596;18,11;1,05;190,44;303,94
252_9083 | O² , I. Imiler, Chf-uone | SA;885-417-0377;227;906;25,06;0,80;201,29;182,37


Merci d'avance pour votre aide.

Configuration: Windows / Chrome 93.0.4577.82


A voir également:

3 réponses

mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
Modifié le 15 oct. 2021 à 13:03
Bonjour,

Voici comment tu peux faire en
python
, en s'appuyant sur le caractère @ qu'on va temporairement utiliser comme une virgule décimale. Cela présuppose que @ n'est pas utilisé par ailleurs dans le reste de ton fichier, et si c'est le cas, il suffit d'utiliser n'importe quel autre caractère absent de ton fichier. C'est un peu limitant mais ça a le mérite de la simplicité.

toto.txt

"252_2773 | O² , Cabet  , Sa Gein ye | SA,738-654 5163,289,1 596,""18,11"",""1,05"",""190,44"",""303,94"""
"252_9083 | O² , I. Imiler, Chf-uone | SA,885-417-0377,227,906,""25,06"",""0,80"",""201,29"",""182,37"""


toto.py

#!/usr/bin/env python3

import re, sys
for line in sys.stdin:
    line = line.strip().strip('"')
    line = re.sub('""(\d+),(\d+)""', "\\1@\\2", line)
    line = line.replace(',', ';').replace('@', ',')
    print(line)


Quelques explications :
  • l1: On écrit le script en python3 (il faut donc que python soit installé, e.g.
    sudo apt update && sudo apt install python3
    );
  • l3: On importe les modules nécessaires au script.
  • l4: On lit l'entrée standard ligne par ligne (ce qui permettra d'utiliser le script dans un pipe).
  • l5: On supprime le retour à la ligne et les guillemets en début et fin de ligne.
  • l6: On remplace chaque nombre décimal entouré de guillemets (e.g.
    ""12,34""
    ) par la partie entière, suivi de @, suivi de la partie décimale (e.g.
    12@34
    ). Pour cela on utilise le module
    re
    qui implémente les expressions régulières.
  • l7: On remplace les virgules séparateur par
    ;
    , puis les
    @
    (nos "virgules décimales") par
    ,
    .
  • l8: On écrit la ligne corrigée sur la sortie standard.


Exécution

(mando@silk) (~) $ cat toto.txt | python3 toto.py 
252_2773 | O² ; Cabet ; Sa Gein ye | SA;738-654 5163;289;1 596;18,11;1,05;190,44;""303;94
252_9083 | O² ; I. Imiler; Chf-uone | SA;885-417-0377;227;906;25,06;0,80;201,29;""182;37


Améliorations possibles
  • Tu peux rendre toto.py exécutable, la ligne 1 permet de sous entendre l'interpréteur.


chmod a+x toto.py
cat toto.txt | ./toto.py
  • Si tu places ce script dans un dossier référencé dans ton
    PATH
    (voir dans ton shell
    echo $PATH
    ), typiquement
    /usr/local/bin/toto.py
    tu ne seras plus obligé d'expliciter le chemin vers ton script python :


sudo mv toto.py /usr/local/bin/
cat toto.txt | toto.py
  • ... et tu peux même le renommer si tu le souhaites, éventuellement sans extension .py


sudo mv /usr/local/bin/toto.py /usr/local/bin/moulinette
cat toto.txt | moulinette


Remarque

Tu peux si tu le souhaites adapter cette approche en shell e.g. en utilisant la commande
sed
.

Bonne chance
1
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
Modifié le 19 oct. 2021 à 18:02
Bonjour,

Oui il y avait quelques petites erreurs que je n'avais pas vues, voici le programme corrigé :

Code :

import re, sys
for line in sys.stdin:
    line = re.sub('""(\d+),(\d+)""', "\\1@\\2", line)
    line = line.strip().strip('"')
    i = line.rfind("|") 
    line = line[:i] + line[i:].replace(',', ';').replace('@', ',')
    print(line)


Quelques explications :
  • Il faut corriger les valeurs décimales avant de virer les guillemets aux extrémités, sans quoi la dernière valeur décimale n'est pas capturée par
    re.sub
    , vu que le guillemet fermant de la dernière valeur a disparu.
  • Il faut chercher le début du 3e champ (ma variable
    i
    ) afin de ne remplacer les virgules et @ que sur la partie de la chaîne derrière le dernier
    |
    .
  • Ensuite on récupère l'ancien contenu de
    line
    avant
    i
    , et on procède aux différents remplacements dans la partie au delà de
    i
    .


Résultat :

252_2773 | O² , Cabet  , Sa Gein ye | SA;738-654 5163;289;1 596;18,11;1,05;190,44;303,94
252_9083 | O² , I. Imiler, Chf-uone | SA;885-417-0377;227;906;25,06;0,80;201,29;182,37


Note que par rapport à ce que tu attends j'obtiens "738-654 5163" alors que tu attendais "38-654-5163" mais je pense qu'il s'agit d'une erreur de ta part ?

Bonne chance
1
pcsystemd Messages postés 691 Date d'inscription dimanche 27 novembre 2005 Statut Membre Dernière intervention 15 janvier 2024 22
Modifié le 19 oct. 2021 à 16:58
Merci @mamiemando.

Je viens de tester mais il y a un souci sur deux points :

- Certaines doubles côtes ne sont pas supprimées.
- Les virgules du champ "O² , Cabet , Sa Gein ye" sont aussi remplacer par le séparateur ; alors qu'il ne faut pas

cat fichier.txt | python3 test.py 
252_2773 | O² ; Cabet ; Sa Gein ye | SA;738-654 5163;289;1 596;18,11;1,05;190,44;""303;94
252_9083 | O² ; I. Imiler; Chf-uone | SA;885-417-0377;227;906;25,06;0,80;201,29;""182;37



0