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 :

Problème d'extraction de données d'un fichier


Sujet :

Shell et commandes GNU

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Septembre 2016
    Messages : 5
    Points : 1
    Points
    1
    Par défaut Problème d'extraction de données d'un fichier
    Bonjour tout le monde,

    Je me tourne vers vous car je rencontre un problème assez embêtant.

    Pour planter le décor je ne suis pas un expert en bash mais j'essaie tout de même de comprendre et d'apprendre. Par contre je dois admettre que j'ai beaucoup de mal avec les commandes grep et sed. Je n'arrive jamais a trouver les bons arguments pour faire ce que je souhaite faire.

    J'ai passé ces deux derniers jours à parcourir le net pour comprendre et trouver des solutions à mon problème mais impossible.

    Concernant mon problème j'ai deux fichiers différents dont je veux extraire des information précises. Les deux fichiers ressemble à ça :

    gamer.txt


    Running command 'rconcmd' for instance 'TheIsland'
    "
    0. [GdK] Inity, 76561198029054012
    1. Jean Claude, 75475434525234523
    2. Ludovic, 324654665765867567
    "


    Dans ce fichier les deux premières lignes et la dernière ne m'intéresse pas du tout (ligne 1 : Running command 'rconcmd' for instance 'TheIsland' et ligne 2 : "). Ce qui m’intéresse dans chaque ligne c'est (en prenant exemple sur la ligne 3) le pseudo : [GdK] Inity et l'id : 76561198029054012. Chacune de ces deux valeurs devra être injecté dans une variable.

    Mon script pour ceci ressemble à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while read lnid; do
    		ligneid=`echo $lnid | sed 's/\"//g'`
    		temppseudo=`echo $ligneid | sed -n 's/.*(\..*\),.*/\1/p'`
    		tempid=`echo $ligneid | egrep -o '[[:digit:]]*'`
    done < gamer.txt
    Malheureusement pour l'id egrep -o '[[:digit:]]* me retourne tous les chiffres de la ligne , mais je n'ai que besoin de la deuxième suite de chiffre sans le chiffre en début de ligne. Comment faire ?

    chat.txt


    Running command 'rconcmd' for instance 'TheIsland'
    "
    [GdK] Inity (Inity): le message envoyé par l'utilisateur dans le chat
    Mario76 (Jean Claude): Je suis un noob
    Alexdu93 (Ludovic): Kevin qui Rox du poney
    "


    Dans ce fichier les deux premières lignes et la dernière ne m'intéresse pas du tout (ligne 1 : Running command 'rconcmd' for instance 'TheIsland' et ligne 2 : "). Ce qui m’intéresse dans chaque ligne c'est (en prenant exemple sur la ligne 3) le pseudo : [GdK] Inity id : Inity et le message : le message envoyé par l'utilisateur dans le chat. Chacune de ces deux valeurs devra être injecté dans une variable.

    Mon script actuellement ressemble à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    while read ln; do
    		ligne=`echo $ln | sed 's/\"//g'`
                    pseudoIG=`echo $ligne | sed -n 's/.*(\(.*\)).*/\1/p'`
    		message=`echo $ligne | sed 's/.*\(: .*\)/\1/'`
    		pseudoST=`echo $ligne | sed 's/ *(.*//'`
    done < chat.txt
    Et cela semble bien fonctionner ... mais peut-être vous avez une idée plus rapide et plus simple.

    Voilà je vous remercie d'avance pour votre aide.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 550
    Points : 19 383
    Points
    19 383
    Par défaut
    Bonjour,

    je te recommande d'utiliser, de préférence, awk pour ce type de fichier, qui, finalement, peut être résumé à une table de BDD (si l'on omet les deux premières et la dernière lignes (ce que peut faire gawk))

    bon, on peut le faire en 100% bash :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ rgx='^"'
    $ while read line; do if ((++n>1)) && [[ ! $line =~ $rgx ]]; then IFS=',.' read id username userID <<<"$line"; printf '%s\n' "$id" "${username/# /}" "${userID/# /}"; fi; done <gamer.txt
    0
    [GdK] Inity
    76561198029054012
    1
    Jean Claude
    75475434525234523
    2
    Ludovic
    324654665765867567 fichier.txt
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Septembre 2016
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Woaouh,

    merci pour ton scripte N_BaH. Je viens de le tester et ca marche très bien. Par contre je n'arrive pas a comprendre son fonctionnement. Je l'ai décomposé en plusieurs lignes, te serais-t-il possible de m'expliquer la boucle if s'il te plait ?

    Je voudrais appliquer la même chose à gamer.txt

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 550
    Points : 19 383
    Points
    19 383
    Par défaut
    entre parenthèses, il y a une évaluation arithmétique, et
    les crochets doubles initient un test amélioré, avec un opérateur de comparaison de regex.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Septembre 2016
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Quels sont les patterns utilisés pour séparer les différents éléments ?

    Est-ce ?

    ou

    Désolé pour la question stupide mais je veux vraiment comprendre ? Et si c'est la deuxième proposition pourquoi les patterns sont dans le sens inverses ?

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 550
    Points : 19 383
    Points
    19 383
    Par défaut
    c'est l'IFS (Internal Field Separator), qui considère tous les caractères indiqués comme autant de séparateurs potentiels.

    la regex, elle, "recherche" les lignes qui commencent par ".
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Septembre 2016
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Puis-je utiliser les parenthèses comme séparateur aussi ? Si oui pour extraire le mot entre parenthèses (car oui le "(Inity)" sera toujours entre parenthèses) je dois utiliser un truc du style (*) ?

    Les lignes ne commencent pas par " .... juste une, donc comment peut il analyser toutes les lignes ?

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 550
    Points : 19 383
    Points
    19 383
    Par défaut
    Citation Envoyé par inity Voir le message
    Puis-je utiliser les parenthèses comme séparateur aussi ? Si oui pour extraire le mot entre parenthèses (car oui le "(Inity)" sera toujours entre parenthèses) je dois utiliser un truc du style (*) ?

    Les lignes ne commencent pas par " .... juste une, donc comment peut il analyser toutes les lignes ?
    dans l'ordre :
    • oui
    • non, l'IFS est une liste de caractères dont chaque item est un séparateur potentiel, pas un développement de chemin, ni une regex.
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      $ IFS='abc' read -a array <<<"le lapin se cache sous la barrière" 
      $ printf '%s<séparateur\n' "${array[@]}"
      le l<séparateur
      pin se <séparateur
      <séparateur
      <séparateur
      he sous l<séparateur
       <séparateur
      <séparateur
      rrière<séparateur
      $
      ici, j'utilise un tableau parce que je ne connais pas, a priori, le nombre de champs.
      a est un séparateur
      b est un séparateur
      c est un séparateur
    • le script lit une ligne à la fois.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Septembre 2016
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Merci mille fois pour ton aide. Malheureusement je n'arrive pas à l'appliquer à chat.txt. J'ai tout de même réussi à finir mon script en utilisant sed et grep.

    Par contre quand je le lance il consomme énormément de temps CPU. Si quelqu'un peux jeter un coup d’œil et me conseiller des optimisation de code je vous en serai extrêmement redevable.

    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    #!/bin/bash
     
    #Un bot pour surveiller le chat d'ARK
     
    				#Variables
    		###############################
    		#	   $username = Pseudo Steam		   #
    		#  $userID = ID Steam de la liste des joueurs  #
    		#      $steamname = Pseudo Steam du chat    #
    		#             $pseudo = Nom InGame		   #
    		#          $message = Message du chat		   #
    		#         $players[$username]=$userid		   #
    		#	   $jail[$steamname]=$jailpts		   #
    		###############################
     
    #Boucle infinie
    while true; do
     
    	#Récupération du chat
    	rm chat.txt
    	/usr/local/bin/arkmanager rconcmd "GetChat" @$1 > chat.txt
    	sed -i '/Running/ d' chat.txt
    	sed -i '/processed/ d' chat.txt
    	sed -i '/Oyez oyez/ d' chat.txt
    	sed -i -e "s/\[//g" chat.txt
            sed -i -e "s/\]//g" chat.txt
    	sed -i '/pour son language deplace/ d' chat.txt
     
    	#Récupération des joueurs
    	rm gamer.txt
    	/usr/local/bin/arkmanager rconcmd "ListPlayers" @$1 > gamer.txt
    	sed -i -e "s/\[//g" gamer.txt
    	sed -i -e "s/\]//g" gamer.txt
     
    	#Traitement de gamer.txt pour avoir liste players[$username]=$userID
    	rgx='^"'
     
    	while read line; do
    		if ((++n>1)) && [[ ! $line =~ $rgx ]]; then
    			IFS=',.' read id username userID <<<"$line"
    			printf '%s\n' "${username/# /}" "${userID/# /}"
    			uname=`echo $username | sed 's/\ //g'`
    			uID=`echo $userID | sed 's/\ //g'`
    			players["$uname"]="$uID"
    		fi
    	done <gamer.txt
     
    	#Traitement de chat.txt
     
    	while read ln; do
    		temp=`echo $ln | sed 's/\"//g'`
    		temp2=`echo $temp | sed 's/\://g'`
    		ligne=`echo $temp2 | sed 's/\ //g'`
    		pseudo=`echo $ligne | sed -n 's/.*(\(.*\)).*/\1/p'`
    		tmpmessage=`echo $temp | sed 's/.*\(: .*\)/\1/'`
    		message=`echo $tmpmessage | sed 's/\: //g'`
    		steamname=`echo $ligne | sed 's/ *(.*//'`
     
    		#Test si un de mot du message est contenu dans la liste filtre
    		for i in `cat filter.txt`; do
    		id=${players[$steamname]}
    		echo $message > tmp.txt
    		echo $i
    		mot=`grep -i -c "$i" tmp.txt`
    		if [ $mot != "0" ]; then
     
    				#Test si deja kick 4 fois, si oui ban si non kick
    				if [ ${jail[$steamname]} == "1111"]; then
    					/usr/local/bin/arkmanager rconcmd "BanPlayer $id" @all
    					/usr/local/bin/arkmanager rconcmd "ServerChat Le joueur $pseudo a etait banni pour son language deplace." @all
    					#For debug uncomment
    					#exit 0
    				else
    					/usr/local/bin/arkmanager rconcmd "KickPlayer $id" @$1
    					/usr/local/bin/arkmanager rconcmd "ServerChat Le joueur $pseudo $id a etait kick pour son language deplace." @$1
    					#For debug uncomment
    					#exit 0
    				fi
    		fi
    		done
    done <chat.txt
     
    #Demonter les variables
    unset players
    done
    Le but du scripte étant de récupérer les données du chat dans chat.txt et les données des joueurs connectés dans gamer.txt. Puis les messages du chat doivent être comparé au mots dans filtre.txt (je souhaite absolument le garder en txt pour faciliter l'administration par d'autres personnes). Si un mot dans le message correspond à un des mot de filtre.txt le script doit kicker le joueurs ayant envoyé le message. Au bout de 5 kicks le joueurs se voit banni.

    Je ne sais pas si la consommation de cpu viens du fait que j'ai mis le tout dans une boucle infinie while afin que le scripte tourne non stop.

    Voilà j'espère que toutes ces données vous permettrons de m'aider.

  10. #10
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    salut,

    Citation Envoyé par N_BaH Voir le message
    la regex, elle, "recherche" les lignes qui commencent par ".
    d'ailleurs si j'ai bien compris il y a les lignes qui commencent par " et également la première ligne qu'il faut zapper, est-ce que ce ne serait pas plus pertinent de ne prendre que les lignes qui matchent ^[0-9] directement ?

    Citation Envoyé par inity Voir le message
    je n'arrive pas à l'appliquer à chat.txt.
    à sa décharge ton post initial était un peu brouillon, perso j'ai pas tout compris en le lisant, la "compréhension sélective" que j'en ai eu m'aurait amené à faire la même chose que N_BaH, mais d'après ce que tu dis ça ne suffit pas

Discussions similaires

  1. Extraction de données dans un fichier texte en VB6 !
    Par rockroa dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 21/06/2006, 16h00
  2. Perl: Extraction de données d'un fichier texte ?
    Par fifto dans le forum Langage
    Réponses: 1
    Dernier message: 27/03/2006, 16h01
  3. [VB]extraction de données d'un fichier
    Par latevi dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 30/01/2006, 12h03
  4. Extraction de donnés dans un fichier XML
    Par ANISSS dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 27/01/2006, 13h16
  5. Extraction de données sur des fichiers excel
    Par iupgeii dans le forum MFC
    Réponses: 3
    Dernier message: 23/01/2004, 13h53

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