IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linux Discussion :

Traiter un fichier en ignorant les répétitions


Sujet :

Linux

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Octobre 2009
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 26
    Par défaut Traiter un fichier en ignorant les répétitions
    Bonsoir,

    Je cherche à traiter des chaines de caractères situé dans un fichier mais ne sachant pas où trouver mes premières commande après plusieurs essais raté je suis bloqué. Je recherche plus des commandes où creuser mes recherches que des solutions toutes pondue mais je suis pas contre ;-)

    Dans un fichier j'ai une liste comme ceci (liste de paquet, dépôt et leur clé)

    paquet1, deb http://blabla.com jaunty main, 098UY935
    paquet2, deb http://blabla.com jaunty main, 098UY935
    paquet3, deb http://blublu.com jaunty main, 12RT56U8
    paquet3, deb http://blublu.com jaunty main, 12RT56U8
    paquet4, deb http://bloblo.com jaunty main, 23GJGH45

    J'ai essayer avec la fonction gawk mais je suis un peut perdu. A part afficher les résultats je n'arrive pas à les utiliser pour les placer dans des fichiers ou des commandes

    gawk -F", *" '{print $2}' a-tester affiche deb http://blabla.com jaunty main
    gawk -F", *" '{print $3}' a-tester affiche 098UY935

    La suite où je bloque le plus est comment ignorer les informations qui ce répète (adresse de dépôt et/ou clé de dépôt) afin d'éviter des traitement inutile, actuellement j'approche les 900 paquets à traiter (dépôt local). Je pensait aux tableaux mais je ne suis pas sur que ce soit une bonne idée.

    Voilou, je suis plus bloqué par manque de connaissance des commandes disponible qu'autre chose et ça sape la motivation quand on ce retrouve à fouiller dans toutes les directions à la fois et à l'aveuglette.

    Merci par avance pour vos conseils

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 676
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 676
    Par défaut
    Bonjour percherie,

    Je ne suis pas sûr de bien comprendre.
    Tu veux faire afficher les champs 2 et 3 dans des fichiers différents ? comme ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    awk -F', ' '{print $2 > "fichier01.out"; print $3 > "fichier02.out"}' a-tester
    cat fichier01.out
    deb http://blabla.com jaunty main
    deb http://blabla.com jaunty main
    deb http://blublu.com jaunty main
    deb http://blublu.com jaunty main
    deb http://bloblo.com jaunty main
    cat fichier02.out
    098UY935
    098UY935
    12RT56U8
    12RT56U8
    23GJGH45
    mais cette ligne ne va pas supprimer les doublons
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 853
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 853
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par percherie Voir le message
    Bonsoir,

    Je cherche à traiter des chaines de caractères situé dans un fichier mais ne sachant pas où trouver mes premières commande après plusieurs essais raté je suis bloqué. Je recherche plus des commandes où creuser mes recherches que des solutions toutes pondue mais je suis pas contre ;-)

    Dans un fichier j'ai une liste comme ceci (liste de paquet, dépôt et leur clé)

    paquet1, deb http://blabla.com jaunty main, 098UY935
    paquet2, deb http://blabla.com jaunty main, 098UY935
    paquet3, deb http://blublu.com jaunty main, 12RT56U8
    paquet3, deb http://blublu.com jaunty main, 12RT56U8
    paquet4, deb http://bloblo.com jaunty main, 23GJGH45

    J'ai essayer avec la fonction gawk mais je suis un peut perdu. A part afficher les résultats je n'arrive pas à les utiliser pour les placer dans des fichiers ou des commandes

    gawk -F", *" '{print $2}' a-tester affiche deb http://blabla.com jaunty main
    gawk -F", *" '{print $3}' a-tester affiche 098UY935

    La suite où je bloque le plus est comment ignorer les informations qui ce répète (adresse de dépôt et/ou clé de dépôt) afin d'éviter des traitement inutile, actuellement j'approche les 900 paquets à traiter (dépôt local). Je pensait aux tableaux mais je ne suis pas sur que ce soit une bonne idée.

    Voilou, je suis plus bloqué par manque de connaissance des commandes disponible qu'autre chose et ça sape la motivation quand on ce retrouve à fouiller dans toutes les directions à la fois et à l'aveuglette.

    Merci par avance pour vos conseils
    Ta question est un peu obscure alors je vais être très général

    Si tu as un seule ligne d'info à traiter (style date, pwd, id), tu peux stocker simplement cette ligne via les backquottes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    info=`date`
    info=`id`
    info=`pwd`
    Si tu as maintenant un flot d'informations à traiter (un listing de fichiers venus d'un ls, le contenu d'un fichier venu d'un cat, le résultat d'un ping ou d'un traceroute) et que tu dois traiter ces informations ligne par ligne, il te faut un outil de découpage de blocs en ligne.

    Cet outil est donné par read. Et comme t'as plusieurs lignes à traiter, il te faut une boucle de traitement. Il suffit donc de piper le flot d'informations dans une boucle de read
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ls -l |while read ligne
    do
        echo "contenu: $ligne"
    done
    Le ls -l (ou toute autre commande quelconque que t'as envie de traiter) enverra toutes ses lignes au pipe qui le retransmettra au read qui stockera la ligne lue dans la variable "ligne". Tant que le read lit une ligne, il renvoie "vrai" et la boucle se fait, une fois qu'il n'y a plus rien à lire, il renvoie "faux" et la boucle se termine.
    Te voilà donc maintenant avec une boucle de traitement. Et dans cette boucle, tu possèdes une ligne d'information à traiter. Te faut donc un outil de découpage de l'info. L'outil le plus basique est cut. Cet outil te permet d'extraire des champs (à toi de définir quel caractère délimite un champ) ou même des caractères.
    Exemple permettant d'afficher le home de tous les utilisateurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    cat /etc/passwd |while read ligne
    do
        user=`echo $ligne |cut -f1 -d:`
        home=`echo $ligne |cut -f6 -d:`
        echo "Le home de $user est $home"
    done
    A partir de là, t'as en main les outils de base te permettant de manipuler un flot d'informations, quel que soit l'origine du flot. Le reste n'est qu'une question d'algo

    Commandes à assimiler
    - grep => affiche toutes les lignes contenant une chaine demandée
    - cut => coupe des datas en colonnes
    - awk/gawk => permet de programmer un algorithme complexe sur des lignes de datas
    - sed => permet de transformer des datas à la volée
    - tr => autre outil analogue à sed mais avec d'autres possibilités
    - sort => trie un flot de datas
    95% des scripts de traitement d'info n'utilisent que ces quelques commandes
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre expérimenté
    Profil pro
    Ingénieur
    Inscrit en
    Mars 2007
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Mars 2007
    Messages : 199
    Par défaut
    Pour faire chauffer le "man" , je propose les commandes suivantes (en vrac) :

    bash, cat, sed, date, mkdir, echo, read, export, cd, rm, true, false, ls, chgrp, chown
    kill, ln, mount, pwd, sleep, touch, tempfile, uname, ping, df, du, diff, seq, od, tar, cpio
    dd, fdisk, mkfs, grep / egrep, basename, dirname, ps, wc, cut, awk/gawk, tr, sort, uniq
    let / expr / bc, cp, mv, tail, head, find, more / less, who

    test / [ ], if else fi, while do done, until do done, case $var in esac
    for var in liste do done, break, continue, exit, function

    Attention : Pour certaines commandes, l'explication se trouvera au sein du "man bash".

  5. #5
    Membre averti
    Inscrit en
    Octobre 2009
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 26
    Par défaut
    Merci pour les explications je vais pouvoir progresser dans mes compréhension et d'ailleurs je me rend compte que la solution que j'ai trouvé hier est complexe du à l'utilisation de awk alors que cut semble faire ce que je recherche. Je vais refaire un essais.

    D'ailleurs j'aurai une question de syntaxe, avec l'insertion de donnée j'ai un problème de syntaxe mais avec l'utilisation de pipe cela fonctionne mais j'ai également appris que les variables situé dedans sont perdu une fois le pipe terminé. Voici ce que ça donne.

    Code fonctionnel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    # Ajout des dépots avec controle de présence
    awk -F", *" '{print $2}' proglist | sort -u | #on injecte le tri unique sur l'entrée standard de "while read..."
    while read line #on lit ligne à ligne l'entrée standard et on affecte la ligne à la variable "line"
    do
        if ! grep -q "$line" /etc/apt/sources.list; then # on vérifie si la ligne est présente dans le fichier cible
        echo $line | sudo tee -a /etc/apt/sources.list # on l'ajoute au fichier cible
        fi
    done
    Code avec erreur : Syntax error: redirection unexpected
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    # Ajout des dépots avec controle de présence
    while read line #on lit ligne à ligne l'entrée standard et on affecte la ligne à la variable "line"
    do
        if ! grep -q "$line" /etc/apt/sources.list; then # on vérifie si la ligne est présente dans le fichier cible
        echo $line | sudo tee -a /etc/apt/sources.list # on l'ajoute au fichier cible
        fi
    done < <( awk -F", *" '{print $2}' proglist | sort -u ) #on injecte le tri unique sur l'entrée standard de "while read...
    J'aimerai comprendre ce qui cloche, en attendant je vais reprendre tout ça avec la commande cut qui m'a l'air plus simple et peut être moins gourmand en ressource (j'en sais rien du tout en fait).

  6. #6
    Membre averti
    Inscrit en
    Octobre 2009
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 26
    Par défaut
    En traitant le fichier proglist contenant les lignes suivante (il y a des espaces différent après les virgules selon les lignes)
    paquet1, deb http://blabla.com jaunty main , A98UY935
    paquet2, deb http://blibli.com jaunty main, I2345678
    paquet3, deb http://blibli.com jaunty main, I2345678
    paquet4, deb http://blibli.com jaunty main, I2345678
    paquet5, deb http://blabla.com jaunty main, A98UY935
    paquet6, deb http://blabla.com jaunty main, A98UY935
    paquet7, deb http://blublu.com jaunty main, UDH4FK8Z
    paquet8, deb http://blabla.com jaunty main, A98UY935
    Je suis passé de :
    awk -F", *" '{print $2}' proglist | sort -u

    à :
    cut -f2 -d, proglist | sed -e "s/^[ ]*//" | sed -e "s/[ ]*$//" | sort -u

    Quel est la commande la plus intéressante à votre avis? Sinon je n'arrive toujours pas à insérer la nouvelle commande dans la boucle while sans passer par un pipe "|" (voir réponse précédente)

  7. #7
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 676
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 676
    Par défaut
    On peut faire comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while IFS=',' read prems deuz troiz
     do
       echo $deuz
    done < proglist | sort -u |\
       grep -vf /etc/apt/sources.list >> /etc/apt/sources.list
    ...
    ?
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 853
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 853
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par percherie Voir le message
    mais j'ai également appris que les variables situé dedans sont perdu une fois le pipe terminé.
    Effectivement, ca peut être un gros soucis

    Il y a toutefois une méthodes pour pallier le pb en n'utilisant pas de pipe dans le traitement de fichier (c.a.d. remplacer le cat fic |while read lig)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #!/bin/sh
    exec 3<fichier_a_traiter       # Création d'un canal input contenant le fichier
     
    # Lecture du canal 3 (donc le fichier)
    while read lig 0<&3
    do
        echo "ligne: $lig"
    done
    S'il faut traiter un flot issu d'une commande, rien n'interdit alors de rediriger la commande vers un fichier temporaire pour ensuite le traiter de cette façon
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Membre expérimenté
    Profil pro
    Ingénieur
    Inscrit en
    Mars 2007
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Mars 2007
    Messages : 199
    Par défaut
    Envoyé par percherie
    mais j'ai également appris que les variables situé dedans sont perdu une fois le pipe terminé.
    J'ai posté une explication concernant les pertes de variables en cas de "fork", tu peux lire mon intervention (ericduval) dans la discution suivante : http://www.developpez.net/forums/d31...chier-colonne/

    Nota : vous remarquerez la césure de l'URL

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 30/03/2011, 17h17
  2. Réponses: 5
    Dernier message: 19/06/2008, 23h03
  3. awk - ignorer les commentaires d'un fichier
    Par wildmary dans le forum Linux
    Réponses: 5
    Dernier message: 30/10/2007, 15h31
  4. Réponses: 1
    Dernier message: 06/08/2007, 10h39
  5. Réponses: 6
    Dernier message: 05/08/2007, 07h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo