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

Shell et commandes GNU Discussion :

[bash] Rechercher une donnée et la copier vers un autre fichier


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 14
    Par défaut [bash] Rechercher une donnée et la copier vers un autre fichier
    Bonjour à tous,

    J'aimerai pour un fichier personnes contenant des noms/prénoms/adresses/sexes, réalisé un script qui copie uniquement les noms/prénoms des hommes dans un fichier homme et les noms/prénoms des femmes dans un fichier femme.
    Le fichier personnes ressemble à ça :

    Homme Homme Rue de l'Homme 16 M
    Homme Homme Rue de l'Homme 18 M
    Femme Femme Rue de la Femme 20 F

    Je ne vois pas comment accéder au champ sexe, et à partir de ça, copié la ligne avec uniquement le nom/prénom. Le délimiteur (étant la tabulation) me pose également problème, car pour le champ adresse par exemple, il y en a plusieurs, donc la commande cut -d " " -f3 ne me mènera à rien. En plus de ça, je ne peux pas connaitre le nombre exacte de colonne que peut prendre l'adresse, ce qui corse encore plus la chose.

    Quelques pistes pour résoudre le problème serait la bienvenue.

    D'avance, merci.

    P.S. : Je débute dans les scripts bash, soyez indulgent. ^^

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 851
    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 851
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Le shell n'est qu'un mortier permettant d'assembler divers outils dédiés aux traitements variés dont on a besoin quotidiennement. Et comme Unix/Linux est quasiment géré/paramétré par des fichiers textes, Unix/Linux regorge d'outils dédiés à la manipulation de ces fichiers texte.
    Donc tout ce que tu as à faire est de connaitre et savoir utiliser ces outils et comme ça tu n'as plus rien à faire d'autre dans tes scripts que de les appeler quand tu en as besoin.

    Citation Envoyé par Mendozaa Voir le message
    Quelques pistes pour résoudre le problème serait la bienvenue.
    Bon, déjà le très basique grep (Global Regular Expression Print/Parser/Pattern), outil dédié à extraire certaines lignes d'un fichier en fonction d'un motif sensé s'y trouver
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    grep " M$" personnes >hommes            # Redirige vers le fichier "hommes" toutes les lignes se terminant par " M" (attention, j'ai mis une tabulation devant "M" puisque c'est le délimiteur)
    grep " F$" personnes >femmes            # Même principe
    Tu remarqueras que plus le motif demandé est large, moins il y a de risque d'obtenir de mauvais résultats. J'aurais parfaitement pu demander juste "M". Mais en demandant " M", j'élimine le risque (éventuel) de voir surgir des lignes se terminant accidentellement par "xxxM" (comme par exemple des lignes de commentaires). Bien entendu je n'élimine pas le risque de récupérer une ligne de commentaire se terminant par " M" (le risque zéro n'existe pas) mais ensuite tout est une question de rapport "complexité de l'algo/probabilité du risque à gérer"...

    Ensuite, si tu veux créer un algo plus complexe, style "que les hommes majeurs" ou autre, alors faudra passer par le très puissant mais un peu plus complexe "awk". Il s'agit d'un outil dédié au traitement de fichiers textes dans lequel tu as instantanément accès de façon individuelle à chaque mot de ta ligne (awk traitant en effet le fichier ligne par ligne) par sa position numérotée dans la ligne préfixée par un "$" ($1, $2, $3, ...) et dans lequel tu peux programmer un algo complet (avec des boucles, des alternatives, des variables) selon la valeur de ces mots.

    Exemple
    Code awk : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '{if ($NF == "M" && $(NF - 1) > 18) printf("%s\n", $0)}' personnes
    NF étant le nombre de mots de la ligne en cours, $NF symbolise alors le dernier mot de la ligne et $(NF - 1) l'avant dernier. Et $0 représente la ligne entière.

    Bon ce petit exemple est minime comparé aux possibilités qu'offre awk qui méritent un livre complet. Bien entendu, plus un outil est puissant plus il est complexe à mettre en oeuvre et lourd à s'exécuter donc le choix d'utiliser tel ou tel outil aura alors une forte influence sur la rapidité de ton script...
    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]

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 14
    Par défaut
    Malheureusement, nous n'avons pas vu la fonction awk au cours, donc je ne pourrai pas l'utiliser pour ce script. Néanmoins, les deux grep me conviennent parfaitement.

    Du coup, j'ai réussi à soutirer les noms/prénoms du fichier comme ça : grep "M$" personnes | cut -f1-2 > hommes

    J'ai d'ailleurs essayé ceci : grep "M$" personnes | tr -s " " | cut -f1-2 > hommes, ce qui me donne le même résultat, seulement les doublons d'espace ne sont pas supprimer. Est-ce que la tabulation n'est pas considéré comme une suite d'espace ?

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 851
    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 851
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Mendozaa Voir le message
    Malheureusement, nous n'avons pas vu la fonction awk au cours, donc je ne pourrai pas l'utiliser pour ce script.
    Exact. Surtout que chaque exercice donné est toujours réalisable avec les outils déjà vus. Et attention, awk n'est pas une fonction mais un outil (un programme externe indépendant). La force du shell est en effet de pouvoir utiliser ces outils comme si c'étaient des fonctions mais ce n'en sont pas...

    Citation Envoyé par Mendozaa Voir le message
    Du coup, j'ai réussi à soutirer les noms/prénoms du fichier comme ça : grep "M$" personnes | cut -f1-2 > hommes
    Oui, je n'avais pas vu que tu ne voulais qu'une partie de la ligne et donc t'as bien trouvé (ne garder avec un cut que les infos utiles de ce qui a été extrait avec grep).
    Et donc t'as bien pigé l'idée du mortier et de l'imbrication des outils => tous les outils ne font que des actions très basiques mais en les liant par des pipes, tu peux réaliser de grandes choses (une fois j'ai transformé un fichier texte en un annuaire LDAP en utilisant 7 pipes). Et si ça ne suffit pas, alors t'as encore à ta disposition des variables te permettant de mémoriser des résultats (var=$(commande)) pour les réutiliser plus tard (echo "$var" | autre_commande)...

    Citation Envoyé par Mendozaa Voir le message
    Est-ce que la tabulation n'est pas considéré comme une suite d'espace ?
    Ben non. La tabulation est un caractère bien précis (code 9 dans la table ascii) alors que l'espace en est un autre (code 32). Faut pas confondre "ce qui est" et "ce que l'écran te montre" surtout quand ce dernier transforme certains caractères pour une vision humaine plus confortable comme par exemple le "return" (symbolisé par un "\n") transformé en une nouvelle ligne...

    Exemple (à essayer toi-même)
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    a=$(seq 10)
    echo $a
    echo "$a"
    echo "$a" |od -c
    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]

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 14
    Par défaut
    J'ai fait ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    #! /bin/sh
     
    if [ $# -lt 1 ]; then
    	echo "Le paramètre est manquant"
    	echo "Press any character to continue"
    	read rien
    	exit 1
    fi
     
    if [ -r $1 ]; then
    	nomM=`grep "M$" $1 | cut -f1`
    	prenomM=`grep "M$" $1 | cut -f2`
    	nomF=`grep "F$" $1 | cut -f1`
    	prenomF=`grep "F$" $1 | cut -f2`
    fi
     
    chaineM="$nomM , $prenomM"
    chaineF="$nomF , $prenomF"
     
    $chaineM > hommes
    $chaineF > femmes
    Est-ce que les deux assignations pour les variables chaineM et chaineF sont correcte ? J'aimerai simplement écrire dans le fichier le nom et le prénom avec une virgule entre les deux.

    En l’exécutant, j'ai une erreur sur les deux dernières lignes. Comment faire comprendre au script que hommes et femmes sont des fichiers et pas des variables ?

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 851
    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 851
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Mendozaa Voir le message
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #! /bin/sh
     
    if [ $# -lt 1 ]; then
    	echo "Le paramètre est manquant"
    	echo "Press any character to continue"
    	read rien
    	exit 1
    fi
    Ok, sauf que le read est inutile. S'il n'y a pas de paramètre alors le script s'arrête et voilà.

    Citation Envoyé par Mendozaa Voir le message
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if [ -r $1 ]; then
    	nomM=`grep "M$" $1 | cut -f1`
    	prenomM=`grep "M$" $1 | cut -f2`
    	nomF=`grep "F$" $1 | cut -f1`
    	prenomF=`grep "F$" $1 | cut -f2`
    fi
    Dommage tous ces grep répétés. N'oublie pas qu'un grep entrainera une lecture et une analyse du fichier. Aussi rapide que ce soit, le temps nécessaire au grep sera ici inutilement doublé...
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    if [ -r $1 ]; then
    	homme=`grep "M$" $1`
    	femme=`grep "F$" $1`
    	nomM=`echo "$homme" | cut -f1`
    	prenomM=`echo "$homme" | cut -f2`
    	nomF=`echo "$femme" | cut -f1`
    	prenomF=`echo "$femme" | cut -f2`
    fi

    Citation Envoyé par Mendozaa Voir le message
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    chaineM="$nomM , $prenomM"
    chaineF="$nomF , $prenomF"
     
    $chaineM > hommes
    $chaineF > femmes

    Est-ce que les deux assignations pour les variables chaineM et chaineF sont correcte ?
    Oui, tout à fait. Sauf que cette assignation est inutile dans le cas où le script n'est pas rentré dans le "if [-r $1]"...

    Citation Envoyé par Mendozaa Voir le message
    En l’exécutant, j'ai une erreur sur les deux dernières lignes. Comment faire comprendre au script que hommes et femmes sont des fichiers et pas des variables ?
    T'as une erreur parce que le premier mot d'une ligne shell doit impérativement être une instruction shell ou une commande. Or, "$chaineM" (étant alors remplacé par son contenu) ne contient pas d'instruction ou de commande !!!

    T'as la solution dans mon exemple d'au dessus...
    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]

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

Discussions similaires

  1. copier une base de données d'un ordinateur vers un autre
    Par ck23 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 13/01/2011, 00h36
  2. Réponses: 20
    Dernier message: 01/02/2008, 14h21
  3. Copier une liste d'un site vers un autre
    Par LefortLudovic dans le forum SharePoint
    Réponses: 4
    Dernier message: 06/09/2007, 14h52
  4. [SQL] Comment rechercher une donnée selon un critère !
    Par Il_TiRaNNo dans le forum PHP & Base de données
    Réponses: 12
    Dernier message: 09/05/2007, 14h59
  5. copier une base d'un serveur vers un autre
    Par julien.63 dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 28/03/2007, 14h18

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