Awk reperer les champs entre " "
Fermé
tid008
Messages postés
8
Date d'inscription
vendredi 13 mars 2009
Statut
Membre
Dernière intervention
31 mars 2009
-
13 mars 2009 à 16:24
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 - 13 mars 2009 à 23:41
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 - 13 mars 2009 à 23:41
4 réponses
mamiemando
Messages postés
33352
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
12 novembre 2024
7 804
13 mars 2009 à 22:47
13 mars 2009 à 22:47
En fait je ne pense pas que ce soit faisaible en awk car il y a une notion de mémoire (guillemets ouvrant et guillemets fermant). Ce sera par ailleurs difficile à faire simplement avec des cut notamment car la ',' n'est pas un séparateur (elle apparaît par exemple dans "Lundi,Mardi, Mercredi, etc.." ).
Donc le plus simple c'est de faire un automate par exemple en C, qui va lire la chaîne caractère par caractère. Avec un système de bascule (variable i dans le programme qui suit) on peut mémoriser si on est en train de lire un caractère situé après un guillemet ouvrant ou un guillemet fermant. Voici comment on peut faire (copie colle ce fichier dans plop.c) :
Le programme se compile avec la commande (remplace pouet par un nom d'exécutable qui te convient) :
Ensuite pour le lancer :
Libre à toi d'utiliser habilement l'opérateur < du shell et les noms de device (/dev/stdout...) si tu veux chaîner ça dans un pipe |.
Exemple : J'ai préparé un fichier plop.txt et je veux générer un fichier pouet.txt :
Ici, on écrit directement sur la sortie standard, et on pipe ça (en tout bien tout honneur) avec un sort pour trier chaque ligne dans l'ordre alphabétique :
Bonne chance
Donc le plus simple c'est de faire un automate par exemple en C, qui va lire la chaîne caractère par caractère. Avec un système de bascule (variable i dans le programme qui suit) on peut mémoriser si on est en train de lire un caractère situé après un guillemet ouvrant ou un guillemet fermant. Voici comment on peut faire (copie colle ce fichier dans plop.c) :
#include <stdio.h> int main(int argc,char **argv){ FILE *fin,*fout; char c; int i = 0; if(argc<2){ fprintf(stderr,"usage: %s filename_in filename_out\n",argv[0]); return 1; } // Ouvrir le 1er fichier en lecture if(!(fin = fopen(argv[1],"r"))){ fprintf(stderr,"can't read %s\n",argv[1]); return 2; } // Ouvrir le 2e fichier en écriture if(!(fout = fopen(argv[2],"w"))){ fprintf(stderr,"can't write %s\n",argv[2]); fclose(fin); return 3; } // Lire le 1er fichier caractère par caractère while( (c = fgetc(fin)) != EOF){ // si on rencontre un guillemet on commence à recopier // le contenu de fin dans fout (ou au contraire on arrête) if(c == '"'){ if(i % 2) fprintf(fout,"\n"); ++i; continue; // on n'écrit pas le caractère courant (") } // si i est impair on écrit le caractère courant if(i % 2) fprintf(fout,"%c",c); } // Fermer les fichiers fclose(fin); fclose(fout); return 0; }
Le programme se compile avec la commande (remplace pouet par un nom d'exécutable qui te convient) :
gcc -W -Wall -o pouet plop.c
Ensuite pour le lancer :
./pouet fichier_entree.txt fichier_sortie.txt
Libre à toi d'utiliser habilement l'opérateur < du shell et les noms de device (/dev/stdout...) si tu veux chaîner ça dans un pipe |.
Exemple : J'ai préparé un fichier plop.txt et je veux générer un fichier pouet.txt :
(mando@aldur) (~) $ cat plop.txt "mais","N'a pas pu démarrer","Jamais", "Lundi,Mardi, Mercredi, etc.." (mando@aldur) (~) $ ./pouet plop.txt pouet.txt (mando@aldur) (~) $ cat pouet.txt mais N'a pas pu démarrer Jamais Lundi,Mardi, Mercredi, etc..
Ici, on écrit directement sur la sortie standard, et on pipe ça (en tout bien tout honneur) avec un sort pour trier chaque ligne dans l'ordre alphabétique :
(mando@aldur) (~) $ ./pouet plop.txt /dev/stdout | sort Jamais Lundi,Mardi, Mercredi, etc.. mais N'a pas pu démarrer
Bonne chance
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 841
13 mars 2009 à 23:05
13 mars 2009 à 23:05
Salut,
Sinon tu peux utiliser sed.
Cdlt
Sinon tu peux utiliser sed.
$ cat ccm "At1","Jamais","N'a pas pu d‚marrer","Jamais","Lundi,Mardi, Mercredi, etc.." $ sed -e 's/","/\n/g' -e 's/"//g' ccm At1 Jamais N'a pas pu d‚marrer Jamais Lundi,Mardi, Mercredi, etc..
Cdlt
mamiemando
Messages postés
33352
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
12 novembre 2024
7 804
13 mars 2009 à 23:12
13 mars 2009 à 23:12
Sauf que... tu as triché :-) Il y avait un espace ici :
Sinon oui en séparant sur la chaîne {","} c'est facile ^^
..."Jamais", "Lundi,Mardi,...
Sinon oui en séparant sur la chaîne {","} c'est facile ^^
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 841
13 mars 2009 à 23:21
13 mars 2009 à 23:21
Sauf que... tu as triché :-) Il y avait un espace ici :
S'il n'y a que ça qui te gênes, tu rajoutes deux étoiles et deux espaces dans le motif, et tu peux même rajouter autant d'espaces que tu veux, que ce soit avant ou après la virgule ;-)
S'il n'y a que ça qui te gênes, tu rajoutes deux étoiles et deux espaces dans le motif, et tu peux même rajouter autant d'espaces que tu veux, que ce soit avant ou après la virgule ;-)
$ cat nono "At1", "Jamais","N'a pas pu d‚marrer","Jamais", "Lundi,Mardi, Mercredi, etc.." $ sed -e 's/" *, *"/\n/g' -e 's/"//g' ccm At1 Jamais N'a pas pu d‚marrer Jamais Lundi,Mardi, Mercredi, etc..
jipicy
Messages postés
40842
Date d'inscription
jeudi 28 août 2003
Statut
Modérateur
Dernière intervention
10 août 2020
4 897
13 mars 2009 à 23:41
13 mars 2009 à 23:41
Salut,
[tmpfs]$ cat plop "At1","Jamais","N'a pas pu d?marrer","Jamais","Lundi,Mardi, Mercredi, etc.." "At1", "Jamais","N'a pas pu d?marrer","Jamais", "Lundi,Mardi, Mercredi, etc.." [tmpfs]$ sed 's/ *,* *"*\([^"]*\) *,* *"/\1\n/g' plop At1 Jamais N'a pas pu d?marrer Jamais Lundi,Mardi, Mercredi, etc.. At1 Jamais N'a pas pu d?marrer Jamais Lundi,Mardi, Mercredi, etc.. [tmpfs]$;-))