Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 01/06/2020, à 10:42

zigroful1

script mélangeant AWK et SED pour analyse fichier csv

Bonjour à tous,
Je travaille sous Ubuntu 18.04 LTS et j'ai voulu faire un script mélangeant AWK et SED me permettant d'analyser un fichier csv  comportant des lignes de cette forme:
12/10/2020; "blabla a1 a2 a3 \n b1 b2 b3\n c1"; d1; 5.8;;
Le séparateur de champs est le ";"
Les blabla a1 a2 a3 b1 etc... sont des alphanumériques, tout ce qu'il y a de plus ordinaire
J'attire l'attention sur le fait que le deuxième champ est entre double guillemets et qu'il y a entre les guillemets des retours à la ligne
Ce que je veux obtenir au final est:
12/10/2020; blabla a1 a2 a3 b1 b2 b3 c1; d1;5.8;;
avec $0 = 12/10/2020
$1 = blabla a1 a2 a3 b1 b2 b3 c1
$2 = d1
$3 = 5.8
$4= " "

j'ai fait le script suivant:
sed 's/\"/ /g' | gawk 'BEGIN{ FS=";"}{ gsub("\n", " ", $2); print $0}'

1- J'élimine les guillemets
2 - J'élimine les retours à la ligne contenus dans $2
Mais ça ne marche pas complètement ! Il élimine bien les guillemets mais il n'élimine pas les \n contenus strictement dans le 2ème champ et lorsque je lui demande de me restituer les champs, il donne:
Pour $1 :
12/10/2020
b1 b2 b3
c1

Pour $2 :
blabla a1 a2 a3
d1

Pour $3:
5.8

Pour $4:
""
Je n'arrive pas à éliminer les \n à l'intérieur du 2ème champ. Quelqu'un a-t-il une idée ?

Hors ligne

#2 Le 01/06/2020, à 11:19

pingouinux

Re : script mélangeant AWK et SED pour analyse fichier csv

Bonjour,
Ceci ?

$ gawk 'BEGIN{ OFS=FS=";"}{ gsub("\"","",$2);gsub("\\\\n", "", $2);print}' <<<'12/10/2020; "blabla a1 a2 a3 \n b1 b2 b3\n c1"; d1; 5.8;;'
12/10/2020; blabla a1 a2 a3  b1 b2 b3 c1; d1; 5.8;;

Hors ligne

#3 Le 01/06/2020, à 12:29

zigroful1

Re : script mélangeant AWK et SED pour analyse fichier csv

Bonjour Pingouinux,
J'ai essayé la propo de solution que vous m'avez transmise, mais je constate sur le terminal que:
1- le deuxième double guillemet n'est pas supprimé
2- Les retours à la ligne subsistent

J'ajoute une difficulté supplémentaire: J'ai besoin d'éliminer les retours à la ligne uniquement du deuxième champ. Naturellement, le retour à la ligne de la fin de l'enregistrement (qui se situe après le double point virgule, subsiste !).
Votre solution ne semble pas fonctionner, chez moi (du moins)
Merci quand même !

Hors ligne

#4 Le 01/06/2020, à 12:40

pingouinux

Re : script mélangeant AWK et SED pour analyse fichier csv

Petite simplification, mais le résultat sera le même qu'en #6.

$ gawk 'BEGIN{ OFS=FS=";"}{ gsub("\"|\\\\n", "", $2);print}' <<<'12/10/2020; "blabla a1 a2 a3 \n b1 b2 b3\n c1"; d1; 5.8;;'
12/10/2020; blabla a1 a2 a3  b1 b2 b3 c1; d1; 5.8;;

Il faut que tu précises ce que tu veux, et que tu montres la commande exacte que tu utilises, son résultat, et le résultat souhaité.
Pour plus de lisibilité, utilise les balises-code : <>

Hors ligne

#5 Le 01/06/2020, à 12:41

zigroful1

Re : script mélangeant AWK et SED pour analyse fichier csv

En revanche j'ai fait :

sed 's/\"/ /g' | sed ':a;N;$!ba; s/\n/ /g'

et là, il supprime tous les guillemets et tous les retours à la ligne, tant et si bien que tout le fichier se retrouve dans une seule ligne.
Le problème, dans ce cas est de redécouper cette unique ligne, juste avant l'occurence des dates (puisque toutes mes lignes commencent par une date). J'ai essayé de redécouper de la manière suivante:

gsub(("[0-3][0-9]/[0-1][0-9]/2020"), "\n\1")

Histoire de remplacer chaque occurence de date, par la date précédée d'un \n
Il redécoupe bien la ligne juste avant chaque date, mais la date est remplacée, en chaque début de ligne, par un caractère bizarre !
Voilà où j'en suis !
Si tu as une idée ?

Dernière modification par Ayral (Le 01/06/2020, à 12:45)

Hors ligne

#6 Le 01/06/2020, à 13:02

pingouinux

Re : script mélangeant AWK et SED pour analyse fichier csv

Si tu as une idée ?

Non, du moins pas avec le peu d'informations que tu donnes.
Si tes données sont dans un fichier, montre au moins quelques lignes du fichier, ainsi que la commande EXACTE que tu lances, le résultat que tu obtiens, et celui que tu souhaites..

Hors ligne

#7 Le 01/06/2020, à 14:07

Watael

Re : script mélangeant AWK et SED pour analyse fichier csv

zigroful1

Voila la donnée, mise sous la variable c dans bash et que j'appelle avec echo -e $c
Dans cette donnée j'y ai mis deux lignes consécutives qui commencent par une date.

12/10/2020; "blabla a1 a2 a3 \n b1 b2 b3\n c1"; d1; 5.8;;\n21/05/2020;"e1 e2 e3\n f1 f2\n g1 g2"; h1;; 12.7
echo -e $c | sed 's/\"/ /g' | gawk 'BEGIN{FS=";"}{gsub("\n"," ",$2); print $0}'
12/10/2020;  blabla a1 a2 a3 
 b1 b2 b3
 c1 ; d1; 5.8;;21/05/2020; e1 e2 e3
 f1 f2
 g1 g2 ; h1;; 12.7
Alors que je veux obtenir: 12/10/2020; blabla a1 a2 a3 b1 b2 b3 c1; 5.8;;
                                          21/05/2020; e1 e2 e3 f1 f2 g1 g2; h1;;12.7

ta variable est moisie. elle sort d'où ?
sed | awk est une mauvaise pratique : awk sait faire ce que fait sed, d'autant plus pour une chose aussi simple.


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#8 Le 01/06/2020, à 14:10

pingouinux

Re : script mélangeant AWK et SED pour analyse fichier csv

Tu as envoyé ta réponse dans une autre discussion : AWK création d'une librairie utilisateur (message #5)
Je ferais ça en python.

$ cat script.py 
import sys, re
s=sys.stdin.read()

# Suppression de tous les '\n'
s=re.sub('\n','',s)

# On place un '\n' devant les dates
def f(k): return '\n'+k.group(0)
s=re.sub("\d{2}/\d{2}/\d{4}",f,s)

print(s)

À appeler ainsi :

echo -e "$c"| python3 script.py

Édité :
Variante plus concise, mais moins lisible (voire illisible…)

import sys, re

def f(k): kg0=k.group(0); return '' if kg0=='\n' else '\n'+kg0
print(re.sub("\n|\d{2}/\d{2}/\d{4}",f,sys.stdin.read()))

Dernière modification par pingouinux (Le 02/06/2020, à 10:52)

Hors ligne

#9 Le 01/06/2020, à 14:19

Watael

Re : script mélangeant AWK et SED pour analyse fichier csv

« variable moisie » : le problème c'est qu'en ne mettant pas le Développement de paramètres entre guillemets, les guillemets que la variable contient n'apparaissent pas.

il faut traiter le fichier csv avec la commande donnée en #4.


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#10 Le 16/06/2020, à 19:12

zigroful1

Re : script mélangeant AWK et SED pour analyse fichier csv

Bonjour à tous,
Je souhaite, à l'aide de sed et/ou awk, rechercher dans un fichier csv un mot, par exemple uber .
je fais sed '/uber/p' fichier.csv
il me sort les lignes contenant uber mais aussi celles contenant uberisation, hubert, urluberlu, entuber, etc...

Comment faire pour qu'il ne me sorte QUE les lignes contenant exactement le mot uber ?

Hors ligne

#11 Le 16/06/2020, à 19:15

kamaris

Re : script mélangeant AWK et SED pour analyse fichier csv

sed -n '/uber/p' fichier.csv

Mais sinon, il existe la commande grep tongue

Hors ligne

#12 Le 16/06/2020, à 19:20

zigroful1

Re : script mélangeant AWK et SED pour analyse fichier csv

Mais avec l'option -n il ne sort rien du tout à l'écran !

Hors ligne

#13 Le 16/06/2020, à 19:24

zigroful1

Re : script mélangeant AWK et SED pour analyse fichier csv

l'option -n n'affiche pas l'état de la mémoire principale (mémoire tampon)

Hors ligne

#14 Le 16/06/2020, à 19:24

kamaris

Re : script mélangeant AWK et SED pour analyse fichier csv

$ echo uber | sed -n '/uber/p'
uber
$ 

Par contre, j'avais pas tout bien lu plus haut : si tu veux que les « mots entiers » uber, il faut l'encadrer par des \b :

$ echo auberb | sed -n '/\buber\b/p'
$ 
$ echo a:uber,b | sed -n '/\buber\b/p'
a:uber,b
$ 

Hors ligne

#15 Le 16/06/2020, à 19:41

zigroful1

Re : script mélangeant AWK et SED pour analyse fichier csv

MERCI ça marche, mais je ne sais pas pourquoi entourer le motif recherché par des \b fonctionne  ! Est-ce que ça fait partie des regexp ?

Hors ligne

#16 Le 16/06/2020, à 19:48

kamaris

Re : script mélangeant AWK et SED pour analyse fichier csv

Hors ligne