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
Bonjour,

je cherche sous awk a recuperer la liste des choses se trouvant entre " "

ex :

"At1","Jamais","N'a pas pu d‚marrer","Jamais", "Lundi,Mardi, Mercredi, etc.."


j'aimerais recuperer pour chaque champ délimité par un " " , le recupere dans un fichier texte

merci de votre aide.

4 réponses

mamiemando Messages postés 33088 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 30 avril 2024 7 751
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) :
#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
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 836
13 mars 2009 à 23:05
Salut,
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
0
mamiemando Messages postés 33088 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 30 avril 2024 7 751
13 mars 2009 à 23:12
Sauf que... tu as triché :-) Il y avait un espace ici :
..."Jamais", "Lundi,Mardi,...

Sinon oui en séparant sur la chaîne {","} c'est facile ^^
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 836
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 ;-)

$ 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.. 
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
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]$
;-))
0